osdteletext-0.9.4/0000755000175000017500000000000012117131615013412 5ustar tobiastobiasosdteletext-0.9.4/storage.c0000644000175000017500000001132412117130631015220 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "storage.h" int Storage::doCleanUp() { DIR *top=opendir(root); int pagesDeleted=0; if (top) { struct dirent *chandir, path; struct stat chandirstat; char fullPath[PATH_MAX]; while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) continue; snprintf(fullPath, PATH_MAX, "%s/%s", root, chandir->d_name); if (stat(fullPath, &chandirstat)==0) { if (S_ISDIR(chandirstat.st_mode)) { pagesDeleted+=cleanSubDir(fullPath); } } } closedir(top); } else { esyslog("OSD-Teletext: Error opening teletext storage directory \"%s\": %s", root, strerror(errno)); } return pagesDeleted; } int Storage::cleanSubDir(const char *dir) { static bool reportedError=false; //avoid filling up syslog DIR *d=opendir(dir); bool hadError=false; int bytesDeleted=0; if (d) { struct dirent *txtfile, path; struct stat txtfilestat; char fullPath[PATH_MAX]; int filesize; while ( (!readdir_r(d, &path, &txtfile) && txtfile != NULL) ) { int len=strlen(txtfile->d_name); //check that the file end with .vtx to avoid accidents and disasters if (strcmp(txtfile->d_name+len-4, ".vtx")==0) { snprintf(fullPath, PATH_MAX, "%s/%s", dir, txtfile->d_name); stat(fullPath, &txtfilestat); filesize=actualFileSize(txtfilestat.st_size); int ret=unlink(fullPath); if (ret==0) bytesDeleted+=filesize; else hadError=ret; } } closedir(d); rmdir(dir); } else { if (!reportedError) { esyslog("OSD-Teletext: Error opening teletext storage subdirectory \"%s\": %s", dir, strerror(errno)); reportedError=true; } } if (hadError && !reportedError) { esyslog("OSD-Teletext: Error removing teletext storage subdirectory \"%s\": %s", dir, strerror(hadError)); reportedError=true; } return bytesDeleted; } Storage::Storage() : byteCount(0), failedFreeSpace(false) { } Storage::~Storage() { } void Storage::freeSpace() { //there might be a situation where only the current directory is left and //occupies the whole space. We cannot delete anything. Don't waste time scanning. if (failedFreeSpace) return; //printf("freeSpace()\n"); time_t min=time(0); char minDir[PATH_MAX]; char fullPath[PATH_MAX]; DIR *top=opendir(getRootDir()); if (top) { int haveDir=0; struct dirent *chandir, path; struct stat chandirstat; while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) continue; snprintf(fullPath, PATH_MAX, "%s/%s", getRootDir(), chandir->d_name); if (stat(fullPath, &chandirstat)==0) { if (S_ISDIR(chandirstat.st_mode)) { if (chandirstat.st_ctime < min && strcmp(fullPath, currentDir)) { min=chandirstat.st_ctime; strcpy(minDir, fullPath); haveDir++; } } } } closedir(top); //if haveDir, only current directory present, which must not be deleted if (haveDir>=2) byteCount-=cleanSubDir(minDir); else failedFreeSpace=true; } } bool Storage::exists(const char* file) { struct stat s; return (stat(file, &s)==0); } void Storage::getFilename(char *buffer, int bufLength, PageID page) { snprintf(buffer, bufLength, "%s/%s/%03x_%02x.vtx", getRootDir(), *page.channel.ToString(), page.page, page.subPage); } void Storage::prepareDirectory(tChannelID chan) { currentDir = cString::sprintf("%s/%s", root, *chan.ToString()); if (!MakeDirs(currentDir, 1)) { esyslog("OSD-Teletext: Error preparing directory for channel \"%s\"", *chan.ToString()); return; } failedFreeSpace=false; } osdteletext-0.9.4/menu.c0000644000175000017500000004733411737124466014552 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include "menu.h" #include "display.h" #include "setup.h" #include "txtrecv.h" #define GET_HUNDREDS(x) ( ( (x) - ((x)%256) ) /256 ) #define GET_TENS(x) ( (( (x) - ((x)%16) )%256 ) /16 ) #define GET_ONES(x) ( (x)%16 ) #define GET_HUNDREDS_DECIMAL(x) ( ( (x) - ((x)%100) ) /100 ) #define GET_TENS_DECIMAL(x) ( (( (x) - ((x)%10) )%100 ) /10 ) #define GET_ONES_DECIMAL(x) ( (x)%10 ) #define PSEUDO_HEX_TO_DECIMAL(x) ( (GET_HUNDREDS_DECIMAL(x))*256 + (GET_TENS_DECIMAL(x))*16 + (GET_ONES_DECIMAL(x)) ) using namespace std; int Stretch = true; typedef map IntMap; IntMap channelPageMap; //static variables int TeletextBrowser::currentPage=0x100; //Believe it or not, the teletext numbers are somehow hexadecimal int TeletextBrowser::currentSubPage=0; tChannelID TeletextBrowser::channel; int TeletextBrowser::currentChannelNumber=0; TeletextBrowser* TeletextBrowser::self=0; TeletextBrowser::TeletextBrowser(cTxtStatus *txtSt,Storage *s) : cursorPos(0), pageFound(true), selectingChannel(false), needClearMessage(false), selectingChannelNumber(-1), txtStatus(txtSt), suspendedReceiving(false), previousPage(currentPage), previousSubPage(currentSubPage), pageBeforeNumberInput(currentPage), lastActivity(time(NULL)), inactivityTimeout(-1), storage(s) { self=this; //if (txtStatus) // txtStatus->ForceReceiving(true); } TeletextBrowser::~TeletextBrowser() { Display::Delete(); self=0; /*if (txtStatus) { if (suspendedReceiving) txtStatus->ForceSuspending(false); txtStatus->ForceReceiving(false); }*/ } void TeletextBrowser::Show(void) { Display::SetMode(Display::mode); ShowPage(); } bool TeletextBrowser::CheckIsValidChannel(int number) { return (Channels.GetByNumber(number) != 0); } void TeletextBrowser::ChannelSwitched(int ChannelNumber) { cChannel *chan=Channels.GetByNumber(ChannelNumber); if (!chan) return; tChannelID chid=chan->GetChannelID(); if (chid==channel || chid==tChannelID::InvalidID) return; channel=chid; //store page number of current channel IntMap::iterator it; channelPageMap[currentChannelNumber] = currentPage; currentChannelNumber=ChannelNumber; currentPage=0x100; currentSubPage=0; //see if last page number on this channel was stored it=channelPageMap.find(ChannelNumber); if (it != channelPageMap.end()) { //found currentPage=(*it).second; } //on the one hand this must work in background mode, when the plugin is not active. //on the other hand, if active, the page should be shown. //so this self-Pointer. if (self) { self->ShowPage(); } } eOSState TeletextBrowser::ProcessKey(eKeys Key) { if (Key != kNone) lastActivity = time(NULL); switch (Key) { case k1: SetNumber(1);break; case k2: SetNumber(2);break; case k3: SetNumber(3);break; case k4: SetNumber(4);break; case k5: SetNumber(5);break; case k6: SetNumber(6);break; case k7: SetNumber(7);break; case k8: SetNumber(8);break; case k9: SetNumber(9);break; case k0: //same behavior for 0 as VDR does it with channels if ((cursorPos==0) && (!selectingChannel)) { //swap variables int tempPage=currentPage; int tempSubPage=currentSubPage; currentPage=previousPage; currentSubPage=previousSubPage; previousPage=tempPage; previousSubPage=tempSubPage; ShowPage(); } else SetNumber(0); break; case kOk: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); if (selectingChannelNumber>0) { if (CheckIsValidChannel(selectingChannelNumber)) ChannelSwitched(selectingChannelNumber); else { needClearMessage=true; Display::DrawMessage(trVDR("*** Invalid Channel ***")); } } else { ShowPage(); } } break; case kBack: return osEnd; case kNone: //approx. every second //checking if page changed if ( pageFound && ttSetup.autoUpdatePage && cursorPos==0 && !selectingChannel && (PageCheckSum() != checkSum) ) { ShowPage(); //check if page was previously not found and is available now } else if (!pageFound && CheckFirstSubPage(0)) { ShowPage(); } else { if (needClearMessage) { needClearMessage=false; Display::ClearMessage(); } //updating clock UpdateClock(); } //check for activity timeout if (ttSetup.inactivityTimeout && (time(NULL) - lastActivity > ttSetup.inactivityTimeout*60)) return osEnd; break; case kUp: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } if (cursorPos != 0) { //fully revert cursor SetNumber(-3); } ChangePageRelative(DirectionForward); Display::ShowUpperHalf(); ShowPage(); break; case kDown: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } if (cursorPos != 0) { //fully reset SetNumber(-3); } ChangePageRelative(DirectionBackward); Display::ShowUpperHalf(); ShowPage(); break; case kRight: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } if (cursorPos != 0) { //fully reset SetNumber(-3); } ChangeSubPageRelative(DirectionForward); Display::ShowUpperHalf(); ShowPage(); break; case kLeft: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } if (cursorPos != 0) { //revert cursor SetNumber(-1); break; } ChangeSubPageRelative(DirectionBackward); Display::ShowUpperHalf(); ShowPage(); break; case kRed: case kGreen: case kBlue: case kYellow: //case kUser1:case kUser2:case kUser3:case kUser4:case kUser5: //case kUser6:case kUser7:case kUser8:case kUser9: case kPlay:case kPause:case kStop: case kRecord:case kFastFwd:case kFastRew: if (cursorPos != 0) { //fully reset SetNumber(-3); } ExecuteAction(TranslateKey(Key)); break; default: break; } return osContinue; } void TeletextBrowser::ExecuteAction(eTeletextAction e) { switch (e) { case Zoom: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } switch (Display::GetZoom()) { case cDisplay::Zoom_Off: Display::SetZoom(cDisplay::Zoom_Upper); break; case cDisplay::Zoom_Upper: Display::SetZoom(cDisplay::Zoom_Lower); break; case cDisplay::Zoom_Lower: Display::SetZoom(cDisplay::Zoom_Off); break; } break; case HalfPage: if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } switch (Display::mode) { case Display::HalfUpper: Display::SetMode(Display::HalfLower); break; case Display::HalfLower: Display::SetMode(Display::Full); break; case Display::Full: Display::SetMode(Display::HalfUpper); break; } ShowPage(); break; case SwitchChannel: selectingChannelNumber=0; selectingChannel=true; ShowAskForChannel(); break; /*case SuspendReceiving: if (!txtStatus) break; //if (suspendedReceiving) // txtStatus->ForceSuspending(false); //else // txtStatus->ForceSuspending(true); //suspendedReceiving=(!suspendedReceiving); break;*/ case DarkScreen: ChangeBackground(); break; default: //In osdteletext.c, numbers are thought to be decimal, the setup page //entries will display them in this way. It is a lot easier to do the //conversion to hexadecimal here. //This means, we convert the number to what it would be if the string //had been parsed with hexadecimal base. int pageNr=PSEUDO_HEX_TO_DECIMAL((int)e); if (0x100<=pageNr && pageNr<=0x899) { if (selectingChannel) { selectingChannel=false; Display::ClearMessage(); } SetPreviousPage(currentPage, currentSubPage, pageNr); currentPage=pageNr; cursorPos=0; currentSubPage=0; Display::ShowUpperHalf(); ShowPage(); } break; } } // 3-state toggling between configured->transparent->black. // If configured is black or transparent, do 2-state transparent->black only. void TeletextBrowser::ChangeBackground() { tColor clrConfig = (tColor)ttSetup.configuredClrBackground; tColor clrCurrent = Display::GetBackgroundColor(); if (clrCurrent == clrConfig) if (clrConfig == clrTransparent) Display::SetBackgroundColor(clrBlack); else Display::SetBackgroundColor(clrTransparent); else if (clrCurrent == clrBlack) if (clrConfig == clrBlack) Display::SetBackgroundColor(clrTransparent); else Display::SetBackgroundColor(clrConfig); else // clrCurrent == clrTransparent Display::SetBackgroundColor(clrBlack); } eTeletextAction TeletextBrowser::TranslateKey(eKeys Key) { switch(Key) { case kRed: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyRed]; case kGreen: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyGreen]; case kYellow: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyYellow]; case kBlue: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyBlue]; case kPlay: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPlay]; //case kPause: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPause]; case kStop: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyStop]; //case kRecord: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyRecord]; case kFastFwd: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastFwd]; case kFastRew: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastRew]; default: return (eTeletextAction)100; //just to keep gcc quiet } } void TeletextBrowser::SetNumber(int i) { //cursorPos means insertion after, 0<=cursorPos<=2 if (selectingChannel) { selectingChannelNumber = selectingChannelNumber*10+i; ShowAskForChannel(); return; } //i<0 means revert cursor position if (i<0) { for (;i<0;i++) { switch (cursorPos) { case 0: return; case 1: currentPage = currentPage-256*GET_HUNDREDS(currentPage)+256*GET_HUNDREDS(pageBeforeNumberInput); break; case 2: currentPage = currentPage-16*GET_TENS(currentPage)+16*GET_TENS(pageBeforeNumberInput); break; } cursorPos--; } ShowPageNumber(); return; } static int tempPage; switch (cursorPos) { case 0: if (i<1) i=1; //accept no 9 when cursorPos==0 if (i>8) i=8; tempPage= currentPage; pageBeforeNumberInput = currentPage; currentPage = currentPage-256*GET_HUNDREDS(currentPage)+256*i; break; case 1: if (i<0) i=0; if (i>9) i=9; currentPage = currentPage-16*GET_TENS(currentPage)+16*i; break; case 2: if (i<0) i=0; if (i>9) i=9; currentPage = currentPage-GET_ONES(currentPage)+i; pageBeforeNumberInput = currentPage; SetPreviousPage(tempPage, currentSubPage, currentPage); break; } pageFound=true; //so that "page ... not found" is not displayed, but e.g. 1**-00 if (++cursorPos>2) { cursorPos=0; CheckFirstSubPage(0); Display::ShowUpperHalf(); ShowPage(); } else { ShowPageNumber(); } } //returns whether x, when written in hexadecimal form, //will only contain the digits 0...9 and not A...F //in the first three digits. static inline bool onlyDecimalDigits(int x) { return (( x & 0xE) < 0xA) && (( (x>>4) & 0xE) < 0xA) && (( (x>>8) & 0xE) < 0xA); } //after 199 comes 1A0, but if these pages exist, they contain no useful data, so filter them out int TeletextBrowser::nextValidPageNumber(int start, Direction direction) { do { switch (direction) { case DirectionForward: start++; break; case DirectionBackward: start--; break; } } while (!onlyDecimalDigits(start)); return start; } void TeletextBrowser::ChangePageRelative(Direction direction) { int oldpage = currentPage; int oldSubPage = currentSubPage; do { /*if (back) currentPage--; else currentPage++;*/ currentPage=nextValidPageNumber(currentPage, direction); if (currentPage>0x899) currentPage=0x100; if (currentPage<0x100) currentPage=0x899; // sub page is always 0 if you change the page if (CheckFirstSubPage(0)) { SetPreviousPage(oldpage, oldSubPage, currentPage); return; } } while (currentPage != oldpage); return; } void TeletextBrowser::ChangeSubPageRelative(Direction direction) { int oldsubpage = currentSubPage; do { /*if (back) currentSubPage--; else currentSubPage++;*/ currentSubPage=nextValidPageNumber(currentSubPage, direction); if (currentSubPage > 0x99) currentSubPage=0; if (currentSubPage < 0) currentSubPage=0x99; if (CheckPage()) return; } while (currentSubPage != oldsubpage); return; } bool TeletextBrowser::CheckFirstSubPage(int startWith) { int oldsubpage = currentSubPage; do { if (CheckPage()) return true; //currentSubPage++; currentSubPage=nextValidPageNumber(currentSubPage, DirectionForward); if (currentSubPage > 0x99) currentSubPage=0; if (currentSubPage < 0) currentSubPage=0x99; } while (currentSubPage != oldsubpage); return false; } bool TeletextBrowser::CheckPage() { StorageHandle fd; if (!(fd=storage->openForReading(PageID(channel, currentPage, currentSubPage), false)) ) return false; storage->close(fd); return true; } //sets the previousPage variables if and only if new page is different from old page void TeletextBrowser::SetPreviousPage(int oldPage, int oldSubPage, int newPage) { if (oldPage != newPage) { previousPage=oldPage; previousSubPage=oldSubPage; } } void TeletextBrowser::ShowPage() { if ((pageFound=DecodePage())) { if (ttSetup.autoUpdatePage) checkSum=PageCheckSum(); } } void TeletextBrowser::ShowPageNumber() { char str[8]; sprintf(str, "%3x-%02x", currentPage, currentSubPage); if (cursorPos>0) { str[2]='*'; if (cursorPos==1) str[1]='*'; } Display::DrawPageId(str); } void TeletextBrowser::ShowAskForChannel() { if (selectingChannel) { cString str = cString::sprintf(selectingChannelNumber > 0 ? "%s%d" : "%s", tr("Channel (press OK): "), selectingChannelNumber); Display::DrawMessage(str); } } //this is taken and adapted from the teletext plugin since it uses its data bool TeletextBrowser::DecodePage() { // Load the page and decodes it unsigned char cache[40*24+12]; StorageHandle fd; // Take a look if there is a xxx-00 page if (currentSubPage==0) { if ( !(fd=storage->openForReading(PageID(channel, currentPage,currentSubPage), false)) ) { // There is no subpage 0 so look if there is subpage 1 currentSubPage++; // Generate file string } else { // yes file exists storage->close(fd); } } if ( (fd=storage->openForReading(PageID(channel, currentPage, currentSubPage), true)) ) { storage->read(cache,sizeof cache,fd); // Read full page data storage->close(fd); Display::HoldFlush(); Display::ClearMessage(); Display::RenderTeletextCode(cache); ShowPageNumber(); UpdateClock(); Display::ReleaseFlush(); } else { // page doesn't exist currentSubPage--; Display::HoldFlush(); ShowPageNumber(); char str[80]; snprintf(str,80, "%s %3x-%02x %s",tr("Page"),currentPage, currentSubPage,tr("not found")); Display::DrawMessage(str); Display::ReleaseFlush(); return false; } return true; } int TeletextBrowser::PageCheckSum() { int retSum=0; StorageHandle fd; CheckFirstSubPage(currentSubPage); if ((fd=storage->openForReading(PageID(channel, currentPage, currentSubPage), false)) ) { uchar cache[960]; storage->read(cache, 12, fd); //skip storage->read(cache, sizeof(cache), fd); storage->close(fd); memset(cache+12, 0, 8); //it seems that there the clock is transmitted, ignore changes for (uint i=0;i #include #include "displaybase.h" #include "txtfont.h" cDisplay::cDisplay(int width, int height) : Zoom(Zoom_Off), Concealed(false), Blinked(false), FlushLock(0), Boxed(false), Width(width), Height(height), Background(clrGray50), osd(NULL), ScaleX(1), ScaleY(1), OffsetX(0), OffsetY(0), MessageFont(cFont::GetFont(fontSml)), MessageX(0), MessageY(0), MessageW(0), MessageH(0) { } cDisplay::~cDisplay() { if (osd) delete osd; osd=NULL; } void cDisplay::InitScaler() { // Set up the scaling factors. Also do zoom mode by // scaling differently. if (!osd) return; int height=Height-6; int width=Width-6; OffsetX=3; OffsetY=3; switch (Zoom) { case Zoom_Upper: height=height*2; break; case Zoom_Lower: OffsetY=OffsetY-height; height=height*2; break; default:; } ScaleX=(480<<16)/width; ScaleY=(250<<16)/height; } void cDisplay::InitPalette() { cBitmap *bm; if (!osd) return; int Area=0; while ((bm=osd->GetBitmap(Area))) { enumTeletextColor c; bm->Reset(); // reset palette for (c=ttcFirst;c<=ttcLast;c++) bm->Index(GetColorRGB(c,Area)); // Announce all palette colors in defined order int x1,y1,x2,y2; if (!bm->Dirty(x1,y1,x2,y2)) { // force bitmap dirty to update palette bm->SetIndex(bm->X0(),bm->Y0(),*bm->Data(bm->X0(),bm->Y0())); // otherwise palette change wont be displayed on flush } Area++; } } bool cDisplay::SetBlink(bool blink) { int x,y; bool Change=false; if (blink==Blinked) return false; // touch all blinking chars for (y=0;y<25;y++) { for (x=0;x<40;x++) { if (Page[x][y].GetBlink()) { Page[x][y].SetDirty(true); Change=true; } } } Blinked=blink; if (Change) Dirty=true; Flush(); return Change; } bool cDisplay::SetConceal(bool conceal) { int x,y; bool Change=false; if (conceal==Concealed) return false; // touch all concealed chars for (y=0;y<25;y++) { for (x=0;x<40;x++) { if (Page[x][y].GetConceal()) { Page[x][y].SetDirty(true); Change=true; } } } Concealed=conceal; if (Change) Dirty=true; Flush(); return Change; } void cDisplay::SetZoom(enumZoom zoom) { if (!osd) return; if (Zoom==zoom) return; Zoom=zoom; // Re-initialize scaler to let zoom take effect InitScaler(); // Clear screen - mainly clear border CleanDisplay(); Flush(); } void cDisplay::SetBackgroundColor(tColor c) { Background=c; InitPalette(); CleanDisplay(); Flush(); } void cDisplay::CleanDisplay() { cBitmap *bm; enumTeletextColor bgc=(Boxed)?(ttcTransparent):(ttcBlack); int Area=0; while ((bm=osd->GetBitmap(Area))) { // Draw rect in two steps to avoid zapping palette bm->DrawRectangle(bm->X0(), bm->Y0() , bm->X0()+bm->Width()-1, bm->Y0() , bm->Color(GetColorIndex(bgc,Area))); bm->DrawRectangle(bm->X0(), bm->Y0()+1, bm->X0()+bm->Width()-1, bm->Y0()+bm->Height()-1, bm->Color(GetColorIndex(bgc,Area))); // Yes, this *is* stupid. // Otherwise, ttcTransparent would shift into 0 index of palette, // causing palette re-organization and flicker on page change Area++; } // repaint all Dirty=true; DirtyAll=true; } tColor cDisplay::GetColorRGB(enumTeletextColor ttc, int Area) { switch (ttc) { case ttcBlack: return Background; case ttcRed: return clrRed; case ttcGreen: return clrGreen; case ttcYellow: return clrYellow; case ttcBlue: return clrBlue; case ttcMagenta: return clrMagenta; case ttcCyan: return clrCyan; case ttcWhite: return clrWhite; case ttcTransparent: return clrTransparent; default: return Background; } } tColor cDisplay::GetColorRGBAlternate(enumTeletextColor ttc, int Area) { return GetColorRGB(ttc,Area); } void cDisplay::RenderTeletextCode(unsigned char *PageCode) { // Interprete teletext code referenced by PageCode // and draw the whole page content into OSD. // PageCode must be a 40*24+12 bytes buffer HoldFlush(); cRenderPage::ReadTeletextHeader(PageCode); if (!Boxed && (Flags&0x60)!=0) { Boxed=true; CleanDisplay(); } else if (Boxed && (Flags&0x60)==0) { Boxed=false; CleanDisplay(); } cRenderPage::RenderTeletextCode(PageCode+12); ReleaseFlush(); } void cDisplay::DrawDisplay() { int x,y; int cnt=0; if (!IsDirty()) return; // nothing to do for (y=0;y<25;y++) { for (x=0;x<40;x++) { if (IsDirty(x,y)) { // Need to draw char to osd cnt++; cTeletextChar c=Page[x][y]; c.SetDirty(false); if ((Blinked && c.GetBlink()) || (Concealed && c.GetConceal())) { c.SetChar(0x20); c.SetCharset(CHARSET_LATIN_G0_DE); } DrawChar(x,y,c); Page[x][y]=c; } } } Dirty=false; DirtyAll=false; } inline bool IsPureChar(unsigned int *bitmap) { // Check if character is pure foreground or // pure background color int i; if (bitmap[0]==0x0000) { for (i=1;i<10;i++) { if (bitmap[i]!=0x0000) return false; } } else if (bitmap[0]==0xfff0) { for (i=1;i<10;i++) { if (bitmap[i]!=0xfff0) return false; } } else { return false; } return true; } void cDisplay::DrawChar(int x, int y, cTeletextChar c) { unsigned int buffer[10]; unsigned int *charmap; cBitmap *bm; // Get character face: charmap=GetFontChar(c,buffer); if (!charmap) { // invalid - clear buffer bzero(&buffer,sizeof buffer); charmap=buffer; } // Get colors enumTeletextColor ttfg=c.GetFGColor(); enumTeletextColor ttbg=c.GetBGColor(); if (c.GetBoxedOut()) { ttbg=ttcTransparent; ttfg=ttcTransparent; } // Virtual box area of the character cBox box; box.SetToCharacter(x,y); // OSD top left pixel of char cVirtualCoordinate TopLeft; TopLeft.VirtualToPixel(this,box.XMin,box.YMin); // This pixel overlaps the box, but may be almost outside. // Move in OSD pixel units until we are inside the box while (TopLeft.VirtXGetBitmap(Area))) { cVirtualCoordinate BMTopLeft=TopLeft; // Correct for bitmap offset BMTopLeft.OsdX-=bm->X0(); BMTopLeft.OsdY-=bm->Y0(); // Map color to local int fg=GetColorIndex(ttfg,Area); int bg=GetColorIndex(ttbg,Area); if (ttfg!=ttbg && fg==bg && !IsPureChar(charmap)) { // Color collision bg=GetColorIndexAlternate(ttbg,Area); } // Now draw the character. Start at the top left corner, and walk // through all pixels on OSD. To speed up, keep one pointer to OSD pixel // and one to virtual box coordinates, and move them together. cVirtualCoordinate p=BMTopLeft; while (p.VirtY<=box.YMax) { // run through OSD lines // OSD line in this bitmap? if (0<=p.OsdY && p.OsdYHeight()) { // bits for this line int bitline; bitline=charmap[(p.VirtY-box.YMin)>>16]; p.OsdX=BMTopLeft.OsdX; p.VirtX=BMTopLeft.VirtX; while (p.VirtX<=box.XMax) { // run through line pixels // pixel insied this bitmap? if (0<=p.OsdX && p.OsdXWidth()) { // pixel offset in bitline: int bit=(p.VirtX-box.XMin)>>16; if (bitline&(0x8000>>bit)) { bm->SetIndex(p.OsdX,p.OsdY,fg); } else { bm->SetIndex(p.OsdX,p.OsdY,bg); } } p.IncPixelX(this); } } p.IncPixelY(this); } Area++; } } void cDisplay::DrawText(int x, int y, const char *text, int len) { // Copy text to teletext page cTeletextChar c; c.SetFGColor(ttcWhite); c.SetBGColor(ttcBlack); c.SetCharset(CHARSET_LATIN_G0); // Copy chars up to len or null char while (len>0 && *text!=0x00) { c.SetChar(*text); SetChar(x,y,c); text++; x++; len--; } // Fill remaining chars with spaces c.SetChar(' '); while (len>0) { SetChar(x,y,c); x++; len--; } // .. and display Flush(); } void cDisplay::DrawClock() { char text[9]; time_t t=time(0); struct tm loct; localtime_r(&t, &loct); sprintf(text, "%02d:%02d:%02d", loct.tm_hour, loct.tm_min, loct.tm_sec); DrawText(32,0,text,8); } void cDisplay::DrawMessage(const char *txt) { const int border=5; cBitmap *bm; if (!osd) return; HoldFlush(); // Hold flush until done ClearMessage(); // Make sure old message is gone if (IsDirty()) DrawDisplay(); // Make sure all characters are out, so we can draw on top int w=MessageFont->Width(txt)+4*border; int h=MessageFont->Height(txt)+4*border; int x=(Width-w)/2; int y=(Height-h)/2; int Area=0; while ((bm=osd->GetBitmap(Area))) { // Walk through all OSD areas // Get local color mapping tColor fg=bm->Color(GetColorIndex(ttcWhite,Area)); tColor bg=bm->Color(GetColorIndex(ttcBlack,Area)); if (fg==bg) bg=bm->Color(GetColorIndexAlternate(ttcBlack,Area)); // Draw framed box bm->DrawRectangle(x ,y ,x+w-1 ,y+border-1 ,fg); bm->DrawRectangle(x ,y+h-border,x+w-1 ,y+h-1 ,fg); bm->DrawRectangle(x ,y ,x+border-1 ,y+h-1 ,fg); bm->DrawRectangle(x+w-border,y ,x+w-1 ,y+h-1 ,fg); bm->DrawRectangle(x+border ,y+border ,x+w-border-1,y+h-border-1,bg); // Draw text bm->DrawText(x+2*border,y+2*border,txt, fg, bg, MessageFont); Area++; } // Remember box MessageW=w; MessageH=h; MessageX=x; MessageY=y; // And flush all changes ReleaseFlush(); } void cDisplay::ClearMessage() { if (!osd) return; if (MessageW==0 || MessageH==0) return; // map OSD pixel to virtual coordinate, use center of pixel int x0=(MessageX-OffsetX)*ScaleX+ScaleX/2; int y0=(MessageY-OffsetY)*ScaleY+ScaleY/2; int x1=(MessageX+MessageW-1-OffsetX)*ScaleX+ScaleX/2; int y1=(MessageY+MessageH-1-OffsetY)*ScaleY+ScaleY/2; // map to character x0=x0/(12<<16); y0=y0/(10<<16); x1=(x1+(12<<16)-1)/(12<<16); y1=(y1+(10<<16)-1)/(10<<16); for (int x=x0;x<=x1;x++) { for (int y=y0;y<=y1;y++) { MakeDirty(x,y); } } MessageW=0; MessageH=0; Flush(); } osdteletext-0.9.4/rootdir.c0000644000175000017500000000157212117130631015242 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "rootdir.h" const char *RootDir::root = "/var/cache/vdr/vtx"; void RootDir::setRootDir(const char *newRoot) { root=newRoot; } const char *RootDir::getRootDir() { return root; } osdteletext-0.9.4/HISTORY0000644000175000017500000002726012117131127014503 0ustar tobiastobiasVDR Plugin 'osdteletext' Revision History ----------------------------------------- 2013-03-10: version 0.9.4 - Allow to override the CXXFLAGS - Fixed CZ font and added CZ-SK subset - patch provided Marek Hajduk (Closes #1134) - Dropped backwards compatibility for VDR 1.6.0 (Closes #944) - Using new standard plugin Makefile from VDR 1.7.39 2012-04-03: version 0.9.3 - VDR 1.7.27 compatibility (Closes #919), Credit goes to nox and gda fro vdrportal.de - Instead of doing mixed drawing to cOsd and cBitmap only draw to cBitmap (Closes #899, this should fixe the issues with the TT6400) 2012-03-25: version 0.9.2 - Some code refactorings (Thx to Ville Skyttä) - FF card transfer mode on channel switch with VDR >= 1.7.25 (Closes: #9) (Thx to Udo Richter) - VDR 1.7.26 compatibility (Thx to Ville Skyttä) - Better live view channel switch detection 2011-08-20: version 0.9.1 - Updated Italian translation provided by Diego Pierotto (Closes #450) - Added Slovak translation provided by Milan Hrala (Closes #558) 2010-11-06: version 0.9.0 - Updated Italian translation provided by Diego Pierotto (Closes #151) - Fix valid page number check in TeletextBrowser::ExecuteAction (Closes #154) - Fixed possible segfault (Closes #179) - (Thx to Manuel Reimer) - Added setup option to disable main menu entry (Closes #149) (Thx to Manuel Reimer!) - Added command line option to enable storing TopText pages, which is now disabled by default (References #177) (Thx to Andreas Brachold!) - Makefile adjustments for VDR 1.7.13. - Don't care if the current channel really changed, if we get a channel switch on the primary device (Thx to Sören Moch) 2009-06-02: version 0.8.3 - Updated Ukrainian translation provided by Yarema P. aka Knedlyk (Closes #133) 2009-05-25: version 0.8.2 - More refactoring of the TxtStatus class (Thx to Sören Moch!) - Install plug-in to lib dir with --remove-destination as suggested by Christian Wieninger (Closes #57) - If background is configured to completely black or transparent, toggle between black and transparent only. - Updated Italian translation provided by Diego Pierotto (Closes #60) - Fixed problems with VDR >= 1.7.3 (not all teletext pages accessible, 4 GByte VTX files) - Removed unnecessary DVBDIR from Makefile 2009-01-10: version 0.8.1 - Small bugfix in channel switching code 2009-01-10: version 0.8.0 - Added Portuguese translation provided by Chris Silva - Updated Italian translation by Davide Cavalca - Removed the "OSD" from the main menu entry as suggested by Davide Cavalca - Added Ukrainian translation provided by Yarema P. aka Knedlyk - Removed obsolete options -R and -r - Remove remnants of VDR < 1.6 support - Updated Russian translation provided by Oleg Roitburd (Closes #46) - Improved error handling - Background toggling now allows to switch between black, the configured background transparency and full transparency as suggested by Walter K. (Closes #41) - Removed the OSDTELETEXT_REINSERTION_PATCH (dead code) - Removed timingdebug code - Merged class ChannelStatus into cTxtStatus and changed the code that detects, if the current live channel has been changed and the OsdTeletext receiver needs to switch to the new channel as well - Updated French translation provided by Nival Michaël (Closes #56) 2008-12-19: version 0.7.0 - switched completely to VDR 1.6's I18N system and removed the old crap - no more support for older VDR versions! (thx to Rolf Ahrenberg) - proper translation of the key bindings (thx to Rolf Ahrenberg) - Partially updated Italian translation by Davide Cavalca 2008-12-02: version 0.6.0 - Moved installation of README and manpage from all to install target - Updated code for VDR 1.6.0 - Changed default location of vtx cache to /var/cache/vdr/vtx - Fixed problems with switching channels on FF+Budget systems See: http://www.vdr-portal.de/board/thread.php?postid=728192#post728192 2005-08-16: version 0.5.1 - show page if it was initially not found but is received later (suggested by Luca Olivetti) - added timeout for user inactivity after which the plugin is closed. Without timeout the plugin would prevent VDR's auto-shutdown mechanism if it remains open. The value is the same as VDR's min user inactivity setup option. (suggested by Peter Bieringer) - fixed gcc4 warnings (thanks to Ville Skyttä) - updated Finnish translation (thanks to Rolf Ahrenberg) - added command line parameter documentation to READMEs - added /var/cache/vdr/osdteletext to the list of recommended cache directories (suggested by Ville Skyttä) 2005-04-21: version 0.5 Udo Richter: - font subsystem now supports Teletext level 1. Fonts are provided for English, German, French, Italian, Spanish, Portuguese, Swedish and Finnish. The correct font is chosen automatically. - support for "boxed mode" (newstickers, subtitles): in 4Bpp mode the area not covered by the box will be completely transparent - OSD can now be aligned on screen: - in horizontal alignment mode, 0 means on the left, 50 in the center and 100 on the right - in vertical alignment mode, 0 means at the top, 50 in the center and 100 at the bottom - default is central alignment - changed palette system, no longer depending on order of indexing - fixed compilation failure with gcc 2.95 - changed OSD minimum size from 480x324 to 320x250 - some bugfixes and comments in txtrecv.c Marcel Wiesweg: - avoid crash and improve behavior when an invalid channel number is entered 2005-03-30: version 0.5-pre1 Udo Richter: - extensive rewrite of display code - removed display.*, txtbitmap.*, colormapping.h - added txtrender.*, displaybase.*, display.* - menu.c adapted to new display engine - speed improvements by incremental drawing - strict adherence to standard 2005-03-21: version 0.4.9-inofficial - rewrite of scaling and drawing code, better scaling algorithm, removed inefficient double painting. Increases speed by a factor of 4. (Udo Richter) - minor fixes for pagenumber, channel number and clock fields to minimize overdrawing (Rolf Ahrenberg) - fix for graphical errors if normal characters are introduced after double high ones (Rolf Ahrenberg) - fix in receiving code to make osdteletext work with some Swedish channels (thanks to Magnus Andersson) - pseudo target in Makefile allows a simple "make". Previously, this would fail and you needed "make all" 2005-03-03: version 0.4.2 - fixes for double-high characters, scaling and localization (thanks to Rolf Ahrenberg for his patch edition) - adapted to VDR API >= 1.3.18, reentrancy fixes - added Spanish and Catalan translation (thanks to Luca Olivetti) - create stored files with 644 permissions (suggested by Andreas Brachold) 2004-09-21: version 0.4.1 - fixed problem with undefined file permissions of created files (thanks to whoever created the patch) - fixed hexadecimal/decimal misinterpretation for "Jump to" key bindings (thanks to Peter Bieringer for pointing this out) - cosmetic change: key Left when entering channel number now resets the cursor by one position, other keys stop entering of page number 2004-06-18: version 0.4 - ported to VDR 1.3/1.4 series (>=1.3.8 now required) This mostly involved changes in the OSD graphics code, - now supports OSDs with color depth of 3 (thanks to Sascha Volkenandt) - rewrote the storage system: - cache directory is now configurable (option -d) Default value is still /vtx to allow seamless migration, but /tmp/vtx is recommended (conforms to LSB etc.) - changed the default file format: Now more than one page is stored in one file. On filesystems that depend on a blocksize the increases storage efficiency. For tmpfs the improvement factor is approx. 4. - The old system is still available via a command line option (though it now uses a slightly different naming) - when no more space is available on disk or a specified number of harddisk space is exceeded (option -n) the folder least recently modified will be deleted. On exit, all files will be deleted, i.e. (!) on exit, all files with suffix .vtx below the storage directory will be deleted - the option -r is now obsolete (will be ignored) option -R/--no-receive is deprecated - code cleanups, removed broken or unused code - fixed quite a few bugs - Added Russian translation (thanks to Vyacheslav Dikonov) 2003-12-2: version 0.3.2 - receiver now uses a ring buffer and a thread to reduce time spent in Receive() function, thus delaying VDR's receiver thread (several people reported problems with bitstreamout - thanks to Christian Jacobsen and Dr. Werner Fink) - fixed and improved the newly introduced receiver thread (thanks to Dr. Werner Fink) - fixed a bug that if there is a double high title on a page, the last line on that page will be missing (fixed by Rolf Ahrenberg) - fixed Finnish translation (thanks to Rolf Ahrenberg) - added Italian translation (thanks to "kikko77") - fixed bug that you could not enter 0 when switching channel (thanks to Dietmar Hilbrich) 2003-04-28: version 0.3.1 - added support for DXR3 systems. Patches contributed by Kai Moeller and Sascha Volkenandt, thanks to them. - the "0" if pressed as first digit now switches between current and last page (as VDR does it with channels) - fixed autosuspend thread 2003-04-03: version 0.3 - fixed two serious memory leaks, thanks to Martin Pley - added feature to automatically update the page if it changed. - moved color definitions to colormapping.h - made width and height configurable, independent from, but with the same mechanism as VDR - made setup menu items dynamic, i.e. the "Page Number" entries are hidden when "Jump to..." is not selected - Experimental: added option to suspend the receiving automatically for 5min after 30s. This may enable you to use your TV set's teletext decoder if you like to. (patch to VDR needed) - Experimental: added an action to immediately suspend receiving, respectively reenable it - added an action to switch the background color between the value you configured in the setup and black - improved color handling when foreground and background color are the same, thanks to Martin Pley - fixed small bug in ChangePageRelative, thanks to Martin Pley - improvements in page switching, thanks to Martin Pley - rewrote parts of the README - added a German README.DE - several fixes and code clean-ups 2003-02-26: version 0.2.1 - fixed two compiling problems with gcc versions other than 3.2 (asprintf, ) - included Finnish translations, thanks to Lauri Tischler - improved Makefile, now uses install instead of mkdir/cp 2003-02-15: version 0.2 - Copied code to receive and save teletext data from original teletext plugin. (appreciating Peter Seyringer's great work) - added command line option to enable the receiving code - added setup options to make key bindings fully configurable. For each key you can choose between the three actions "Zoom", "Half page" or "Switch channel" or use it to jump to a page - added setup option to make background transparency configurable (0...255, VDR's default value being 127) - included Emil Naepflein's patch to improve changing pages relatively - added feature to view saved pages of other channels than the current ("Switch Channel"). Last pages are remembered over channel switching. - fixed bug when the upper half of a page was not automatically shown when using the number keys - page and channel numbers now persist when returning to VDR - added clock which can regularly be updated. (the clock shows the system time, which may definitely be different from the time broadcast via teletext) - added setup option to enable clock - now copies README to ../../man, as Reinhard Walter Buchner suggested 2003-02-05: Version 0.1 - Initial revision. osdteletext-0.9.4/txtfont.c0000644000175000017500000030165512116726272015306 0ustar tobiastobias// -*- c++ -*- #include "txtfont.h" unsigned int TXT_Mask[11]= { 0x0000, // ************ **** 0x39C0, // **###**###** **** 0x39C0, // **###**###** **** 0x0000, // ************ **** 0x39C0, // **###**###** **** 0x39C0, // **###**###** **** 0x0000, // ************ **** 0x39C0, // **###**###** **** 0x39C0, // **###**###** **** 0x0000 // ************ **** }; unsigned int TXT_Font[][11]= { { // 0x20 = Leerzeichen 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x21 = ! 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x22 = " 0x0000, // ************ **** 0x39C0, // **###**###** **** 0x18C0, // ***##***##** **** 0x3180, // **##***##*** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x23 = # = NC 0x0000, // ************ **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x0000 // ************ **** }, { // 0x24 = $ = NC 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x6660, // *##**##**##* **** 0x6600, // *##**##***** **** 0x3FC0, // **########** **** 0x0660, // *****##**##* **** 0x6660, // *##**##**##* **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0000, // ************ **** }, { // 0x25 = % 0x0000, // ************ **** 0x70C0, // *###****##** **** 0xD980, // ##*##**##*** **** 0x7300, // *###**##**** **** 0x0600, // *****##***** **** 0x0CE0, // ****##**###* **** 0x19B0, // ***##**##*## **** 0x30E0, // **##****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x26 = & 0x0000, // ************ **** 0x1E00, // ***####***** **** 0x3300, // **##**##**** **** 0x3300, // **##**##**** **** 0x1E00, // ***####***** **** 0x3330, // **##**##**## **** 0x61C0, // *##****###** **** 0x3F30, // **######**## **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x27 = ' 0x0000, // ************ **** 0x0700, // *****###**** **** 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x28 = ( 0x0000, // ************ **** 0x0700, // *****###**** **** 0x0C00, // ****##****** **** 0x1800, // ***##******* **** 0x1800, // ***##******* **** 0x1800, // ***##******* **** 0x0C00, // ****##****** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x29 = ) 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0300, // ******##**** **** 0x0180, // *******##*** **** 0x0180, // *******##*** **** 0x0180, // *******##*** **** 0x0300, // ******##**** **** 0x0E00, // ****###***** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x2A = * 0x0000, // ************ **** 0x0600, // *****##***** **** 0x6660, // *##**##**##* **** 0x36C0, // **##*##*##** **** 0x0F00, // ****####**** **** 0x36C0, // **##*##*##** **** 0x6660, // *##**##**##* **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x2B = + 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x2C = , 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3800, // **###******* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** }, { // 0x2D = - 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x2E = . 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1800, // ***##******* **** 0x1800, // ***##******* **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x2F = / 0x0000, // ************ **** 0x00C0, // ********##** **** 0x0180, // *******##*** **** 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0C00, // ****##****** **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x30 = 0 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x31 = 1 0x0000, // ************ **** 0x0700, // *****###**** **** 0x1F00, // ***#####**** **** 0x0700, // *****###**** **** 0x0700, // *****###**** **** 0x0700, // *****###**** **** 0x0700, // *****###**** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x32 = 2 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x30E0, // **##****###* **** 0x00E0, // ********###* **** 0x01C0, // *******###** **** 0x0780, // *****####*** **** 0x1E00, // ***####***** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x33 = 3 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x00C0, // ********##** **** 0x0080, // *******##*** **** 0x07E0, // *****######* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x34 = 4 0x0000, // ************ **** 0x00E0, // ********###* **** 0x03C0, // ******####** **** 0x0700, // *****###**** **** 0x1C00, // ***###****** **** 0x38E0, // **###***###* **** 0x3FE0, // **#########* **** 0x00E0, // ********###* **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x35 = 5 0x0000, // ************ **** 0x3FC0, // **########** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3FC0, // **########** **** 0x00E0, // ********###* **** 0x30E0, // **##****###* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x36 = 6 0x0000, // ************ **** 0x0700, // *****###**** **** 0x0E00, // ****###***** **** 0x1C00, // ***###****** **** 0x3FC0, // **########** **** 0x3860, // **###****##* **** 0x3860, // **###****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x37 = 7 0x0000, // ************ **** 0x7FE0, // *##########* **** 0x01C0, // *******###** **** 0x0380, // ******###*** **** 0x0700, // *****###**** **** 0x0E00, // ****###***** **** 0x1C00, // ***###****** **** 0x3800, // **###******* **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x38 = 8 0x0000, // ************ **** 0x0F80, // ****#####*** **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x0F80, // ****#####*** **** 0x38E0, // **###***###* **** 0x38E0, // **###***###* **** 0x0F80, // ****#####*** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x39 = 9 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x30E0, // **##****###* **** 0x30E0, // **##****###* **** 0x1FC0, // ***#######** **** 0x0380, // ******###*** **** 0x0700, // *****###**** **** 0x0E00, // ****###***** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x3A = : 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0000, // ************ **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x3B = ; 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x1800, // ***##******* **** }, { // 0x3C = < 0x0000, // ************ **** 0x00E0, // ********###* **** 0x0380, // ******###*** **** 0x0E00, // ****###***** **** 0x3800, // **###******* **** 0x0E00, // ****###***** **** 0x0380, // ******###*** **** 0x00E0, // ********###* **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x3D = = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x3E = > 0x0000, // ************ **** 0x7000, // *###******** **** 0x1C00, // ***###****** **** 0x0700, // *****###**** **** 0x01C0, // *******###** **** 0x0700, // *****###**** **** 0x1C00, // ***###****** **** 0x7000, // *###******** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x3F = ? 0x0000, // ************ **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x0180, // *******##*** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** }, { // 0x40 = § = NC 0x0000, // ************ **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x3000, // **##******** **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x1F80, // ***######*** **** 0x00C0, // ********##** **** 0x30C0, // **##****##** **** 0x1F80 // ***######*** **** }, { // 0x41 = A 0x0000, // ************ **** 0x0F00, // ****####**** **** 0x1980, // ***##**##*** **** 0x30C0, // **##****##** **** 0x6060, // *##******##* **** 0x7FE0, // *##########* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x42 = B 0x0000, // ************ **** 0x3FC0, // **########** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FC0, // **########** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x43 = C 0x0000, // ************ **** 0x0FC0, // ****######** **** 0x1860, // ***##****##* **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x1860, // ***##****##* **** 0x0FC0, // ****######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x44 = D 0x0000, // ************ **** 0x3F80, // **#######*** **** 0x30C0, // **##****##** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30C0, // **##****##** **** 0x3F80, // **#######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x45 = E 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3F80, // **#######*** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x46 = F 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3F80, // **#######*** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x47 = G 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x33E0, // **##**#####* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x48 = H 0x0000, // ************ **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x7FE0, // *##########* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x49 = I 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4A = J 0x0000, // ************ **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4B = K 0x0000, // ************ **** 0x30E0, // **##****###* **** 0x3180, // **##***##*** **** 0x3700, // **##*###**** **** 0x3C00, // **####****** **** 0x3700, // **##*###**** **** 0x3180, // **##***##*** **** 0x30E0, // **##****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4C = L 0x0000, // ************ **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4D = M 0x0000, // ************ **** 0x70E0, // *###****###* **** 0x79E0, // *####**####* **** 0x6F60, // *##*####*##* **** 0x6660, // *##**##**##* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4E = N 0x0000, // ************ **** 0x7060, // *###*****##* **** 0x7860, // *####****##* **** 0x6C60, // *##*##***##* **** 0x6660, // *##**##**##* **** 0x6360, // *##***##*##* **** 0x61E0, // *##****####* **** 0x60E0, // *##*****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x4F = O 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x50 = P 0x0000, // ************ **** 0x3FC0, // **########** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FC0, // **########** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x51 = Q 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3360, // **##**##*##* **** 0x1FC0, // ***#######** **** 0x0180, // *******##*** **** 0x00E0 // ********###* **** }, { // 0x52 = R 0x0000, // ************ **** 0x3FC0, // **########** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FC0, // **########** **** 0x3300, // **##**##**** **** 0x31C0, // **##***###** **** 0x30E0, // **##****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x53 = S 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x54 = T 0x0000, // ************ **** 0x7FE0, // *##########* **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x55 = U 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x56 = V 0x0000, // ************ **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x1980, // ***##**##*** **** 0x0F00, // ****####**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x57 = W 0x0000, // ************ **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x6F60, // *##*####*##* **** 0x39C0, // **###**###** **** 0x30C0, // **##****##** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x58 = X 0x0000, // ************ **** 0x30C0, // **##****##** **** 0x1980, // ***##**##*** **** 0x0F00, // ****####**** **** 0x0600, // *****##***** **** 0x0F00, // ****####**** **** 0x1980, // ***##**##*** **** 0x30C0, // **##****##** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x59 = Y 0x0000, // ************ **** 0x6060, // *##******##* **** 0x30C0, // **##****##** **** 0x1980, // ***##**##*** **** 0x0F00, // ****####**** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5A = Z 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0180, // *******##*** **** 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0C00, // ****##****** **** 0x1800, // ***##******* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5B = Ä = NC 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5C = Ö = NC 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5D = Ü = NC 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5E = ^ = NC 0x0600, // *****##***** **** 0x0F00, // ****####**** **** 0x1980, // ***##**##*** **** 0x30C0, // **##****##** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x5F = _ = NC 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x7FE0 // *##########* **** }, { // 0x60 = ° = NC 0x0000, // ************ **** 0x0000, // *****####*** **** 0x0000, // ****##**##** **** 0x0000, // *****####*** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x61 = a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x62 = b 0x0000, // ************ **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x37C0, // **##*#####** **** 0x3860, // **###****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x63 = c 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x1800, // ***##******* **** 0x0FE0, // ****#######* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x64 = d 0x0000, // ************ **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x1F60, // ***#####*##* **** 0x30E0, // **##****###* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FE0, // ***########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x65 = e 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x66 = f 0x0000, // ************ **** 0x07E0, // *****######* **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x3F80, // **#######*** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x67 = g 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1F60, // ***#####*##* **** 0x30E0, // **##****###* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0060, // *********##* **** 0x1FC0 // ***#######** **** }, { // 0x68 = h 0x0000, // ************ **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x37C0, // **##*#####** **** 0x3860, // **###****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x69 = i 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x6A = j 0x0000, // ************ **** 0x00E0, // ********###* **** 0x0000, // ************ **** 0x01E0, // *******####* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x0060, // *********##* **** 0x3060, // **##*****##* **** 0x1FC0 // ***#######** **** }, { // 0x6B = k 0x0000, // ************ **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x30E0, // **##****###* **** 0x3180, // **##***##*** **** 0x3E00, // **#####***** **** 0x3180, // **##***##*** **** 0x30E0, // **##****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x6C = l 0x0000, // ************ **** 0x1E00, // ***####***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x6D = m 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x6DC0, // *##*##*###** **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x6E = n 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x37C0, // **##*#####** **** 0x3860, // **###****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x6F = o 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x70 = p 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x37C0, // **##*#####** **** 0x3860, // **###****##* **** 0x3060, // **##*****##* **** 0x3860, // **###****##* **** 0x37C0, // **##*#####** **** 0x3000, // **##******** **** 0x3000 // **##******** **** }, { // 0x71 = q 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1EC0, // ***####*##** **** 0x31C0, // **##***###** **** 0x30C0, // **##****##** **** 0x31C0, // **##***###** **** 0x1EC0, // ***####*##** **** 0x00C0, // ********##** **** 0x01E0 // *******####* **** }, { // 0x72 = r 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x33E0, // **##**#####* **** 0x3C00, // **####****** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x73 = s 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0060, // *********##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x74 = t 0x0000, // ************ **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x3F80, // **#######*** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x07E0, // *****######* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x75 = u 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x76 = v 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x6060, // *##******##* **** 0x30C0, // **##****##** **** 0x1980, // ***##**##*** **** 0x0F00, // ****####**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x77 = w 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x6060, // *##******##* **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x36C0, // **##*##*##** **** 0x2980, // ***##**##*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x78 = x 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x70E0, // *###****###* **** 0x1980, // ***##**##*** **** 0x0F00, // ****####**** **** 0x1980, // ***##**##*** **** 0x70E0, // *###****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x79 = y 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x18C0, // ***##***##** **** 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0600, // *****##***** **** 0x0C00, // ****##****** **** 0x3800 // **###******* **** }, { // 0x7A = z 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x0180, // *******##*** **** 0x0700, // *****###**** **** 0x0C00, // ****##****** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x7B = ä = NC 0x0000, // ************ **** 0x3180, // **##***##*** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x7C = ö = NC 0x0000, // ************ **** 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x7D = ü = NC 0x0000, // ************ **** 0x10C0, // ***##***##** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x7E = ß = NC 0x0000, // ************ **** 0x0F80, // ****#####*** **** 0x18C0, // ***##***##** **** 0x30C0, // **##****##** **** 0x3380, // **##**###*** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x33C0, // **##**####** **** 0x3000, // **##******** **** 0x3000 // **##******** **** }, { // 0x7F = Block 0x0000, // ************ **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x7FE0, // *##########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x80 = 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x63E0, // *##***#####* **** 0x6660, // *##**##**##* **** 0x6660, // *##**##**##* **** 0x63E0, // *##***#####* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000 // ************ **** }, { // 0x81 = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x82 = 0x0000, // ************ **** 0x3000, // **##******** **** 0x7000, // *###******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3180, // **##***##*** **** 0x0300, // ******##**** **** 0x0660, // *****##**##* **** 0x07E0, // *****######* **** 0x0060 // *********##* **** }, { // 0x83 = 0x0000, // ************ **** 0x0FC0, // ****######** **** 0x1860, // ***##****##* **** 0x0C00, // ****##****** **** 0x3F00, // **######**** **** 0x0C00, // ****##****** **** 0x3E60, // **#####**##* **** 0x33C0, // **##**####** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x84 = 0x0700, // *****###**** **** 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x85 = 0x06C0, // *****##*##** **** 0x0380, // ******###*** **** 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x1800, // ***##******* **** 0x0FE0, // ****#######* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x86 = 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0060, // *********##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x87 = 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x33E0, // **##**#####* **** 0x3C00, // **####****** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x88 = 0x0000, // ************ **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x3980, // ***##**##*** **** 0x0000 // ************ **** }, { // 0x89 = 0x0000, // ************ **** 0x7C00, // *#####****** **** 0x0C00, // ****##****** **** 0x3800, // **###******* **** 0x0C00, // ****##****** **** 0x7980, // *####**##*** **** 0x0300, // ******##**** **** 0x0660, // *****##**##* **** 0x07E0, // *****######* **** 0x0060 // *********##* **** }, { // 0x8A = 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x8B = 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x1C00, // ***###****** **** 0x7FF0, // *########### **** 0x1C00, // ***###****** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x8C = 0x0000, // ************ **** 0x3000, // **##******** **** 0x7000, // *###******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x33C0, // **##**####** **** 0x0660, // *****##**##* **** 0x00C0, // ********##** **** 0x0300, // ******##**** **** 0x07E0 // *****######* **** }, { // 0x8D = 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0380, // ******###*** **** 0xFFE0, // ###########* **** 0x0380, // ******###*** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x8E = 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0F00, // ****####**** **** 0x1F80, // ***######*** **** 0x36C0, // **##*##*##** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600 // *****##***** **** }, { // 0x8F = 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x90 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x3000, // **##******** **** 0x3F80, // **#######*** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x91 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x92 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x18C0, // ***##***##** **** 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0600, // *****##***** **** 0x0C00, // ****##****** **** 0x3800 // **###******* **** }, { // 0x93 = 0x0D80, // ****##*##*** **** 0x0700, // *****###**** **** 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x0180, // *******##*** **** 0x0700, // *****###**** **** 0x0C00, // ****##****** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x94 = 0x0000, // ************ **** 0x6060, // *##******##* **** 0x30C0, // **##****##** **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x6060, // *##******##* **** 0x0000 // ************ **** }, { // 0x95 = 0x001B, // *******##*## **** 0x0C0E, // ****##**###* **** 0x0C00, // ****##****** **** 0x3F80, // **#######*** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x0C00, // ****##****** **** 0x07E0, // *****######* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x96 = 0xFFC0, // ##########** **** 0x0060, // *********##* **** 0x3E30, // **#####***## **** 0x4730, // *#***###**## **** 0x4730, // *#***###**## **** 0x7F30, // *#######**## **** 0x3E30, // **#####***## **** 0x0060, // *********##* **** 0xFFC0, // ##########** **** 0x0000 // ************ **** }, { // 0x97 = 0xFFC0, // ##########** **** 0x0860, // ****#****##* **** 0x1C30, // ***###****## **** 0x0030, // **********## **** 0x7F30, // *#######**## **** 0x0030, // **********## **** 0x1C30, // ***###****## **** 0x0860, // ****#****##* **** 0xFFC0, // ##########** **** 0x0000 // ************ **** }, { // 0x98 = 0x0000, // ************ **** 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x99 = 0x0E00, // ****###***** **** 0x1B00, // ***##*##**** **** 0x0E00, // ****###***** **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9A = 0x0000, // ************ **** 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9B = 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9C = 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9D = 0x0700, // *****###**** **** 0x0700, // *****###**** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9E = 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x9F = _ 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x7FE0 // *##########* **** }, { // 0xA0 = 0x20a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA1 = 0x21a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA2 = 0x22a 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA3 = 0x23a 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA4 = 0x24a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA5 = 0x25a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA6 = 0x26a 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA7 = 0x27a 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA8 = 0x28a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xA9 = 0x29a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAA = 0x2Aa 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAB = 0x2Ba 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAC = 0x2Ca 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAD = 0x2Da 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAE = 0x2Ea 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xAF = 0x2Fa 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xB0 = 0x30a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB1 = 0x31a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB2 = 0x32a 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB3 = 0x33a 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB4 = 0x34a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB5 = 0x35a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB6 = 0x36a 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB7 = 0x37a 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB8 = 0x38a 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xB9 = 0x39a 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBA = 0x3Aa 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBB = 0x3Ba 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBC = 0x3Ca 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBD = 0x3Da 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBE = 0x3Ea 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xBF = 0x3Fa 0xFFFF, // ############ **** 0xFFFF, // ############ **** 0xFFFF, // ############ **** 0xFFFF, // ############ **** 0xFFFF, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00 // ######****** **** }, { // 0xC0 = 0x0600, // *****##***** **** 0x0C00, // ****##****** **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x6060, // *##******##* **** 0x7FE0, // *##########* **** 0x6000, // *##********* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC1 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000 // ************ **** }, { // 0xC2 = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC3 = 0x0000, // ************ **** 0x0FC0, // ****######** **** 0x1860, // ***##****##* **** 0x0C00, // ****##****** **** 0x3F00, // **######**** **** 0x0C00, // ****##****** **** 0x3E60, // **#####**##* **** 0x33C0, // **##**####** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC4 = 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x6660, // *##**##**##* **** 0x6600, // *##**##***** **** 0x3FC0, // **########** **** 0x0660, // *****##**##* **** 0x6660, // *##**##**##* **** 0x3F60, // **########** **** 0x06C0, // *****##***** **** 0x0000 // ************ **** }, { // 0xC5 = 0x3CC0, // **####**##** **** 0x6780, // *##**####*** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC6 = 0x3C60, // **####***##* **** 0x67C0, // *##**#####** **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC7 = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC8 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xC9 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xCA = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xCB = 0x0000, // ************ **** 0x0780, // *****####*** **** 0x0CC0, // ****##**##** **** 0x0780, // *****####*** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xCC = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x1800, // ***##******* **** 0x0FE0, // ****#######* **** 0x0300, // ******##**** **** 0x0E00 // ****###***** **** }, { // 0xCD = 0x0000, // ************ **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0310, // ******###*** **** 0xFFE0, // ###########* **** 0x0310, // ******###*** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xCE = 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0F00, // ****####**** **** 0x1F80, // ***######*** **** 0x36C0, // **##*##*##** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600 // *****##***** **** }, { // 0xCF = 0x0000, // ************ **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x0000 // ************ **** }, { // 0xD0 = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD1 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD2 = 0x0E00, // ****###***** **** 0x1B00, // ***##*##**** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD3 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD4 = 0x0000, // ************ **** 0x1980, // ***##**##*** **** 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD5 = 0x1E60, // ***####**##* **** 0x33C0, // **##**####** **** 0x1F80, // ***######*** **** 0x30C0, // **##****##** **** 0x6060, // *##******##* **** 0x7FE0, // *##########* **** 0x6060, // *##******##* **** 0x6060, // *##******##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD6 = 0x1E60, // ***####**##* **** 0x33C0, // **##**####** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD7 = 0x0000, // ************ **** 0x0FC0, // ****######** **** 0x1860, // ***##****##* **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x1860, // ***##****##* **** 0x0FC0, // ****######** **** 0x0300, // ******##**** **** 0x0E00 // ****###***** **** }, { // 0xD8 = 0x0700, // *****###**** **** 0x0D80, // ****##*##*** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xD9 = 0x0700, // *****###**** **** 0x0D80, // ****##*##*** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xDA = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x1800, // ***##******* **** 0x0FE0, // ****#######* **** 0x0300, // ******##**** **** 0x0E00 // ****###***** **** }, { // 0xDB = 0x0000, // ************ **** 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xDC = 0x0700, // *****###**** **** 0x0D80, // ****##*##*** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xDD = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xDE = 0x0F00, // ****####**** **** 0x1980, // ***##**##*** **** 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xDF = 0x0000, // ************ **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x7FE0, // *##########* **** 0x1980, // ***##**##*** **** 0x1980, // ***##**##*** **** 0x0000 // ************ **** }, { // 0xE0 = 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE1 = 0x0000, // ************ **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0600, // *****##***** **** 0x1800, // ***##******* **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x1F00, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE2 = 0x0000, // ************ **** 0x18C0, // ***##***##** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE3 = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1800, // ***##******* **** 0x3000, // **##******** **** 0x1800, // ***##******* **** 0x0FE0, // ****#######* **** 0x0300, // ******##**** **** 0x0E00 // ****###***** **** }, { // 0xE4 = 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x6660, // *##**##**##* **** 0x6600, // *##**##***** **** 0x3FC0, // **########** **** 0x0660, // *****##**##* **** 0x6660, // *##**##**##* **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0000 // ************ **** }, { // 0xE5 = 0x0000, // ************ **** 0x3F80, // **#######*** **** 0x6180, // *##****##*** **** 0x6180, // *##****##*** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x7FE0, // *##########* **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE6 = 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE7 = 0x1E60, // ***####**##* **** 0x33C0, // **##**####** **** 0x3860, // **###****##* **** 0x3C60, // **####***##* **** 0x3660, // **##*##**##* **** 0x3360, // **##**##*##* **** 0x31E0, // **##***####* **** 0x30E0, // **##****###* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE8 = 0x1E60, // ***####**##* **** 0x33C0, // **##**####** **** 0x0000, // ************ **** 0x37C0, // **##*#####** **** 0x3860, // **###****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xE9 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xEA = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xEB = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x7F80, // *########*** **** 0x00C0, // ********##** **** 0x3FC0, // **########** **** 0x60C0, // *##*****##** **** 0x3FE0, // **#########* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xEC = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3000, // **##******** **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xED = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x0E00, // ****###***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xEE = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xEF = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x0000, // ************ **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x30E0, // **##****###* **** 0x1F60, // ***#####*##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF0 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF1 = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3FE0, // **#########* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF2 = 0x0C00, // ****##****** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x3000, // **##******** **** 0x3F00, // **######**** **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF3 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF4 = 0x19C0, // ***##**##*** **** 0x0000, // ************ **** 0x3FC0, // **########** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x0600, // *****##***** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF5 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF6 = 0x0600, // *****##***** **** 0x0300, // ******##**** **** 0x1FC0, // ***#######** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF7 = 0x0300, // ******##**** **** 0x0600, // *****##***** **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x3060, // **##*****##* **** 0x1FC0, // ***#######** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF8 = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x3DC0, // **####*###** **** 0x0660, // *****##**##* **** 0x3FE0, // **#########* **** 0x6600, // *##**##***** **** 0x3FC0, // **########** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xF9 = 0x0000, // ************ **** 0x0FE0, // ****#######* **** 0x1B00, // ***##*##**** **** 0x3300, // **##**##**** **** 0x7FC0, // *#########** **** 0x6300, // *##***##**** **** 0x6300, // *##***##**** **** 0x63E0, // *##***#####* **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xFA = 0x0000, // ************ **** 0x0300, // ******##**** **** 0x0FC0, // ****######** **** 0x0180, // *******##*** **** 0x1FC0, // ***#######** **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x1F80, // ***######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xFB = 0x0000, // ************ **** 0x3F80, // **#######*** **** 0x30C0, // **##****##** **** 0x3060, // **##*****##* **** 0x7C60, // *#####***##* **** 0x3060, // **##*****##* **** 0x30C0, // **##****##** **** 0x3F80, // **#######*** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0xFC = 0x0000, // ************ **** 0x0000, // ************ **** 0x0180, // *******##*** **** 0x3FC0, // **########** **** 0x6360, // *##***##*##* **** 0x6660, // *##**##**##* **** 0x6C60, // *##*##***##* **** 0x3FC0, // **########** **** 0x1800, // ***##******* **** 0x0000 // ************ **** }, { // 0xFD = 0x0060, // *********##* **** 0x3FC0, // **########** **** 0x61E0, // *##****####* **** 0x6360, // *##***##*##* **** 0x6660, // *##**##**##* **** 0x6C60, // *##*##***##* **** 0x7860, // *####****##* **** 0x3FC0, // **########** **** 0x6000, // *##********* **** 0x0000 // ************ **** }, { // 0xFE = 0x0000, // ************ **** 0x3000, // **##******** **** 0x3000, // **##******** **** 0x3F80, // **#######*** **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x30C0, // **##****##** **** 0x3F80, // **#######*** **** 0x3000, // **##******** **** 0x3000 // **##******** **** }, { // 0xFF = 0x3C00, // **####****** **** 0x1800, // ***##******* **** 0x1F80, // ***######*** **** 0x18C0, // ***##***##** **** 0x18C0, // ***##***##** **** 0x1F80, // ***######*** **** 0x1800, // ***##******* **** 0x3C00, // **####****** **** 0x0000, // ************ **** 0x0000 // ************ **** }, { // 0x60a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x61a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x62a = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x63a = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x64a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x65a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x66a = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x67a = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x68a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x69a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Aa = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Ba = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Ca = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Da = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Ea = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x6Fa = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0 // ******###### **** }, { // 0x70a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x71a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x72a = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x73a = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x74a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x75a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x76a = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x77a = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x78a = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x79a = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Aa = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Ba = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Ca = 0x0000, // ************ **** 0x0000, // ************ **** 0x0000, // ************ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Da = 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFC00, // ######****** **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Ea = 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0x03F0, // ******###### **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0 // ############ **** }, { // 0x7Fa = 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** 0xFFF0, // ############ **** } }; int NationalOptionSubsetG0Default[13]= {0x23,0x94,0x80,0 ,0 ,0 ,0x5e,0x5f,0 ,0 ,0 ,0 ,0 }; int NationalOptionSubsetCZ_SK[13]= {0x23,0x84,0x85,0x95,0x93,0x92,0xed,0x87,0x91,0xeb,0x8f,0xef,0x86}; int NationalOptionSubsetEN[13]= {0x83,0x24,0x80,0x8b,0x8c,0x8d,0x8e,0x23,0x81,0x82,0x88,0x89,0x8a}; int NationalOptionSubsetEE[13]= {0x23,0xc6,0 ,0x5b,0x5c,0 ,0x5d,0xd6,0 ,0x7b,0x7c,0 ,0x7d}; int NationalOptionSubsetFR[13]= {0xd3,0xd4,0xd0,0xdb,0xdc,0xc1,0xde,0x23,0xd1,0xd2,0xd8,0xd9,0xcc}; int NationalOptionSubsetDE[13]= {0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x7b,0x7c,0x7d,0x7e}; int NationalOptionSubsetIT[13]= {0x83,0x24,0xd3,0x60,0xcc,0x8d,0x8e,0x23,0xdd,0xc1,0xc8,0xc9,0xca}; int NationalOptionSubsetLV_LT[13]= {0x23,0x24,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 }; int NationalOptionSubsetPL[13]= {0x23,0 ,0 ,0 ,0 ,0 ,0 ,0xee,0 ,0 ,0 ,0 ,0 }; int NationalOptionSubsetPT_ES[13]= {0xcc,0x24,0xe0,0xeb,0xec,0xed,0xee,0xef,0xe1,0x7d,0xe8,0xc9,0xc2}; int NationalOptionSubsetRO[13]= {0x23,0x94,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0xd2,0 ,0 ,0xde}; int NationalOptionSubsetSR_HR_SL[13]= {0x23,0 ,0 ,0 ,0 ,0xfb,0 ,0xdb,0 ,0 ,0 ,0 ,0 }; int NationalOptionSubsetSV_FI[13]= {0x23,0x94,0x90,0x5b,0x5c,0x9d,0x5d,0x5f,0x91,0x7b,0x7c,0x99,0x7d}; int NationalOptionSubsetTR[13]= {0 ,0 ,0 ,0 ,0x5c,0xd7,0x5d,0 ,0 ,0 ,0x7c,0xcc,0x7d}; inline int NationalOptionSubset(int chr) { switch (chr) { case 0x23: return 0; case 0x24: return 1; case 0x40: return 2; case 0x5b: return 3; case 0x5c: return 4; case 0x5d: return 5; case 0x5e: return 6; case 0x5f: return 7; case 0x60: return 8; case 0x7b: return 9; case 0x7c: return 10; case 0x7d: return 11; case 0x7e: return 12; } return -1; } inline unsigned int LeftBits(unsigned int bits) { // Scale bit positions 0xfc00 to 0xfff0 positions unsigned int res=0; if (bits&0x8000) res|=0xC000; if (bits&0x4000) res|=0x3000; if (bits&0x2000) res|=0x0C00; if (bits&0x1000) res|=0x0300; if (bits&0x0800) res|=0x00C0; if (bits&0x0400) res|=0x0030; return res; } inline unsigned int RightBits(unsigned int bits) { // Scale bit positions 0x03f0 to 0xfff0 positions unsigned int res=0; if (bits&0x0200) res|=0xC000; if (bits&0x0100) res|=0x3000; if (bits&0x0080) res|=0x0C00; if (bits&0x0040) res|=0x0300; if (bits&0x0020) res|=0x00C0; if (bits&0x0010) res|=0x0030; return res; } unsigned int* GetFontChar(cTeletextChar c, unsigned int *buffer) { // Get character bitmap for character/charset enumCharsets font=c.GetCharset(); int chr=c.GetChar(); unsigned int *bitmap=NULL; int i; int NationalOption=NationalOptionSubset(chr); switch (font) { case CHARSET_LATIN_G0: if (NationalOption>=0) { if (NationalOptionSubsetG0Default[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetG0Default[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_EN: if (NationalOption>=0) { if (NationalOptionSubsetEN[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetEN[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_FR: if (NationalOption>=0) { if (NationalOptionSubsetFR[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetFR[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_IT: if (NationalOption>=0) { if (NationalOptionSubsetIT[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetIT[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_PT_ES: if (NationalOption>=0) { if (NationalOptionSubsetPT_ES[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetPT_ES[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_SV_FI: if (NationalOption>=0) { if (NationalOptionSubsetSV_FI[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetSV_FI[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_DE: if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } break; case CHARSET_LATIN_G0_CZ_SK: if (NationalOption>=0) { if (NationalOptionSubsetCZ_SK[NationalOption]>0) bitmap=TXT_Font[NationalOptionSubsetCZ_SK[NationalOption]-0x20]; } else { if (chr>=0x20 && chr<0x80) { bitmap=TXT_Font[chr-0x20]; } } break; case CHARSET_LATIN_G0_EE: case CHARSET_LATIN_G0_LV_LT: case CHARSET_LATIN_G0_PL: case CHARSET_LATIN_G0_RO: case CHARSET_LATIN_G0_SR_HR_SL: case CHARSET_LATIN_G0_TR: // Partially supported latin charsets if (chr>=0x20 && chr<0x80 && NationalOption<0) { bitmap=TXT_Font[chr-0x20]; } break; case CHARSET_LATIN_G2: case CHARSET_CYRILLIC_G0_SR_HR: case CHARSET_CYRILLIC_G0_RU_BG: case CHARSET_CYRILLIC_G0_UK: case CHARSET_CYRILLIC_G2: case CHARSET_GREEK_G0: case CHARSET_GREEK_G2: case CHARSET_ARABIC_G0: case CHARSET_ARABIC_G2: case CHARSET_HEBREW_G0: // totally unsupported break; case CHARSET_GRAPHICS_G1: if (chr>=0x20 && chr<0x40) { bitmap=TXT_Font[chr-0x20+0x80]; } else if (chr>=0x60 && chr<0x80) { bitmap=TXT_Font[chr-0x60+0xE0]; } break; case CHARSET_GRAPHICS_G1_SEP: if (chr>=0x20 && chr<0x40) { bitmap=TXT_Font[chr-0x20+0x80]; } else if (chr>=0x60 && chr<0x80) { bitmap=TXT_Font[chr-0x60+0xE0]; } if (bitmap) { for (i=0;i<10;i++) buffer[i]=bitmap[i]&TXT_Mask[i]; bitmap=buffer; } break; case CHARSET_GRAPHICS_G3: case CHARSET_INVALID: // Totally unsupported break; } if (!buffer) { printf("Warning: Undefined char: %x %x\n",font,chr); return NULL; } switch (c.GetDblHeight()) { case dblh_Top: // Scale top 5 lines to full height buffer[8]=buffer[9]=bitmap[4]; buffer[6]=buffer[7]=bitmap[3]; buffer[4]=buffer[5]=bitmap[2]; buffer[2]=buffer[3]=bitmap[1]; buffer[1]=buffer[0]=bitmap[0]; bitmap=buffer; break; case dblh_Bottom: // Scale bottom 5 lines to full height buffer[0]=buffer[1]=bitmap[5]; buffer[2]=buffer[3]=bitmap[6]; buffer[4]=buffer[5]=bitmap[7]; buffer[6]=buffer[7]=bitmap[8]; buffer[8]=buffer[9]=bitmap[9]; bitmap=buffer; default:; } switch (c.GetDblWidth()) { case dblw_Left: // Scale 6 left columns to full width buffer[0]=LeftBits(bitmap[0]); buffer[1]=LeftBits(bitmap[1]); buffer[2]=LeftBits(bitmap[2]); buffer[3]=LeftBits(bitmap[3]); buffer[4]=LeftBits(bitmap[4]); buffer[5]=LeftBits(bitmap[5]); buffer[6]=LeftBits(bitmap[6]); buffer[7]=LeftBits(bitmap[7]); buffer[8]=LeftBits(bitmap[8]); buffer[9]=LeftBits(bitmap[9]); bitmap=buffer; break; case dblw_Right: // Scale 6 right columns to full width buffer[0]=RightBits(bitmap[0]); buffer[1]=RightBits(bitmap[1]); buffer[2]=RightBits(bitmap[2]); buffer[3]=RightBits(bitmap[3]); buffer[4]=RightBits(bitmap[4]); buffer[5]=RightBits(bitmap[5]); buffer[6]=RightBits(bitmap[6]); buffer[7]=RightBits(bitmap[7]); buffer[8]=RightBits(bitmap[8]); buffer[9]=RightBits(bitmap[9]); bitmap=buffer; default:; } return bitmap; } osdteletext-0.9.4/storage.h0000644000175000017500000000451612117130631015232 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __STORAGE_H #define __STORAGE_H #include "rootdir.h" #include "pageid.h" #define TELETEXT_PAGESIZE 972 struct StorageHandle { public: StorageHandle() { handle=-1; } StorageHandle(const StorageHandle &s) { handle=s.handle; } StorageHandle(int h) { handle=h; } StorageHandle &operator=(int h) { handle=h; return *this; } StorageHandle &operator=(const StorageHandle &s) { handle=s.handle; return *this; } operator bool() const { return handle!=-1; } operator int() const { return handle; } private: int handle; }; enum StorageSystem { StorageSystemLegacy, StorageSystemPacked }; class Storage : public RootDir { public: virtual ~Storage(); enum StorageSystem { StorageSystemLegacy, StorageSystemPacked }; //must be called before the first call to instance() //must be called before operation starts. Set all options (RootDir, maxStorage) before. virtual void cleanUp() = 0; virtual void getFilename(char *buffer, int bufLength, PageID page); virtual void prepareDirectory(tChannelID chan); virtual StorageHandle openForWriting(PageID page) = 0; virtual StorageHandle openForReading(PageID page, bool countAsAccess) = 0; virtual ssize_t write(const void *ptr, size_t size, StorageHandle stream) = 0; virtual ssize_t read(void *ptr, size_t size, StorageHandle stream) = 0; virtual void close(StorageHandle stream) = 0; protected: Storage(); int cleanSubDir(const char *dir); int doCleanUp(); virtual int actualFileSize(int netFileSize) { return netFileSize; } void freeSpace(); bool exists(const char* file); long byteCount; cString currentDir; private: bool failedFreeSpace; }; #endif osdteletext-0.9.4/rootdir.h0000644000175000017500000000156712117130631015253 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __ROOTDIR_H #define __ROOTDIR_H class RootDir { public: static void setRootDir(const char *); static const char *getRootDir(); protected: static const char *root; }; #endif osdteletext-0.9.4/osdteletext.c0000644000175000017500000003653712117131347016142 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * (autogenerated code (c) Klaus Schmidinger) * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include using namespace std; #include "menu.h" #include "txtrecv.h" #include "setup.h" #include "legacystorage.h" #include "packedstorage.h" #if defined(APIVERSNUM) && APIVERSNUM < 10739 #error "VDR-1.7.39 API version or greater is required!" #endif static const char *VERSION = "0.9.4"; static const char *DESCRIPTION = trNOOP("Displays teletext on the OSD"); static const char *MAINMENUENTRY = trNOOP("Teletext"); class cPluginTeletextosd : public cPlugin { private: // Add any member variables or functions you may need here. cTxtStatus *txtStatus; bool startReceiver; bool storeTopText; Storage *storage; int maxStorage; void initTexts(); Storage::StorageSystem storageSystem; public: cPluginTeletextosd(void); virtual ~cPluginTeletextosd(); virtual const char *Version(void) { return VERSION; } virtual const char *Description(void) { return tr(DESCRIPTION); } virtual const char *CommandLineHelp(void); virtual bool ProcessArgs(int argc, char *argv[]); virtual bool Start(void); virtual void Housekeeping(void); virtual const char *MainMenuEntry(void); virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); }; class cTeletextSetupPage; class ActionEdit { public: void Init(cTeletextSetupPage*, int, cMenuEditIntItem *, cMenuEditStraItem *); cMenuEditStraItem *action; cMenuEditIntItem *number; bool visible; }; struct ActionKeyName { const char *internalName; const char *userName; }; class cTeletextSetupPage : public cMenuSetupPage { friend class ActionEdit; private: TeletextSetup temp; int tempPageNumber[LastActionKey]; int tempConfiguredClrBackground; //must be a signed int protected: virtual void Store(void); ActionEdit ActionEdits[LastActionKey]; virtual eOSState ProcessKey(eKeys Key); public: cTeletextSetupPage(void); static const ActionKeyName *actionKeyNames; static const char **modes; //~cTeletextSetupPage(void); //void SetItemVisible(cOsdItem *Item, bool visible, bool callDisplay=false); }; const ActionKeyName *cTeletextSetupPage::actionKeyNames = 0; const char **cTeletextSetupPage::modes = 0; /*class MenuEditActionItem : public cMenuEditStraItem { public: MenuEditActionItem(cTeletextSetupPage *parentMenu, cMenuEditIntItem *pageNumberMenuItem, const char *Name, int *Value, int NumStrings, const char * const *Strings); protected: virtual eOSState ProcessKey(eKeys Key); cTeletextSetupPage *parent; cMenuEditIntItem *pageNumberItem; };*/ cPluginTeletextosd::cPluginTeletextosd(void) : txtStatus(0), startReceiver(true), storage(NULL), maxStorage(-1) { // Initialize any member variables here. // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! } cPluginTeletextosd::~cPluginTeletextosd() { // Clean up after yourself! if (txtStatus) delete txtStatus; if(storage) { storage->cleanUp(); delete storage; } } const char *cPluginTeletextosd::CommandLineHelp(void) { // Return a string that describes all known command line options. return " -d --directory=DIR The directory where the temporary\n" " files will be stored.\n" " (default: /var/cache/vdr/vtx)\n" " Ensure that the directory exists and is writable.\n" " -n --max-cache=NUM Maximum size in megabytes of cache used\n" " to store the pages on the harddisk.\n" " (default: a calculated value below 50 MB)\n" " -s --cache-system=SYS Set the cache system to be used.\n" " Choose \"legacy\" for the traditional\n" " one-file-per-page system.\n" " Default is \"packed\" for the \n" " one-file-for-a-few-pages system.\n" " -t, --toptext Store top text pages at cache. (unviewable pages)\n"; } bool cPluginTeletextosd::ProcessArgs(int argc, char *argv[]) { // Implement command line argument processing here if applicable. static struct option long_options[] = { { "directory", required_argument, NULL, 'd' }, { "max-cache", required_argument, NULL, 'n' }, { "cache-system", required_argument, NULL, 's' }, { "toptext", no_argument, NULL, 't' }, { NULL } }; int c; while ((c = getopt_long(argc, argv, "s:d:n:t", long_options, NULL)) != -1) { switch (c) { case 's': if (!optarg) break; if (strcasecmp(optarg, "legacy")==0) storageSystem = Storage::StorageSystemLegacy; else if (strcasecmp(optarg, "packed")==0) storageSystem = Storage::StorageSystemPacked; break; case 'd': Storage::setRootDir(optarg); break; case 'n': if (isnumber(optarg)) { int n = atoi(optarg); maxStorage=n; } break; case 't': storeTopText=true; break; } } return true; } bool cPluginTeletextosd::Start(void) { // Start any background activities the plugin shall perform. //Clean any files which might be remaining from the last session, //perhaps due to a crash they have not been deleted. switch (storageSystem) { case Storage::StorageSystemLegacy: storage = new LegacyStorage(maxStorage); case Storage::StorageSystemPacked: default: storage = new PackedStorage(maxStorage); } initTexts(); if (startReceiver) txtStatus=new cTxtStatus(storeTopText, storage); if (ttSetup.OSDheight<=100) ttSetup.OSDheight=Setup.OSDHeight; if (ttSetup.OSDwidth<=100) ttSetup.OSDwidth=Setup.OSDWidth; return true; } void cPluginTeletextosd::initTexts() { if (cTeletextSetupPage::actionKeyNames) return; //TODO: rewrite this in the xy[0].cd="fg"; form static const ActionKeyName st_actionKeyNames[] = { { "Action_kRed", trVDR("Key$Red") }, { "Action_kGreen", trVDR("Key$Green") }, { "Action_kYellow", trVDR("Key$Yellow") }, { "Action_kBlue", trVDR("Key$Blue") }, { "Action_kPlay", trVDR("Key$Play") }, { "Action_kStop", trVDR("Key$Stop") }, { "Action_kFastFwd", trVDR("Key$FastFwd") }, { "Action_kFastRew", trVDR("Key$FastRew") } }; cTeletextSetupPage::actionKeyNames = st_actionKeyNames; static const char *st_modes[] = { tr("Zoom"), tr("Half page"), tr("Change channel"), tr("Switch background"), //tr("Suspend receiving"), tr("Jump to...") }; cTeletextSetupPage::modes = st_modes; } void cPluginTeletextosd::Housekeeping(void) { // Perform any cleanup or other regular tasks. } const char *cPluginTeletextosd::MainMenuEntry(void) { return ttSetup.HideMainMenu ? 0 : tr(MAINMENUENTRY); } cOsdObject *cPluginTeletextosd::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. return new TeletextBrowser(txtStatus,storage); } cMenuSetupPage *cPluginTeletextosd::SetupMenu(void) { // Return a setup menu in case the plugin supports one. return new cTeletextSetupPage; } bool cPluginTeletextosd::SetupParse(const char *Name, const char *Value) { initTexts(); // Parse your own setup parameters and store their values. //Stretch=true; if (!strcasecmp(Name, "configuredClrBackground")) ttSetup.configuredClrBackground=( ((unsigned int)atoi(Value)) << 24); else if (!strcasecmp(Name, "showClock")) ttSetup.showClock=atoi(Value); //currently not used else if (!strcasecmp(Name, "suspendReceiving")) ttSetup.suspendReceiving=atoi(Value); else if (!strcasecmp(Name, "autoUpdatePage")) ttSetup.autoUpdatePage=atoi(Value); else if (!strcasecmp(Name, "OSDheight")) ttSetup.OSDheight=atoi(Value); else if (!strcasecmp(Name, "OSDwidth")) ttSetup.OSDwidth=atoi(Value); else if (!strcasecmp(Name, "OSDHAlign")) ttSetup.OSDHAlign=atoi(Value); else if (!strcasecmp(Name, "OSDVAlign")) ttSetup.OSDVAlign=atoi(Value); else if (!strcasecmp(Name, "inactivityTimeout")) /*ttSetup.inactivityTimeout=atoi(Value)*/; else if (!strcasecmp(Name, "HideMainMenu")) ttSetup.HideMainMenu=atoi(Value); else { for (int i=0;i=LastAction) ttSetup.mapKeyToAction[i]=LastAction-1; return true; } } //for migration to 0.4 char act[7]; strncpy(act, Name, 7); if (!strcasecmp(act, "Action_")) return true; return false; } return true; } void cTeletextSetupPage::Store(void) { //copy table for (int i=0;i= LastAction) //jump to page selected ttSetup.mapKeyToAction[i]=(eTeletextAction)tempPageNumber[i]; else //one of the other modes selected ttSetup.mapKeyToAction[i]=temp.mapKeyToAction[i]; } ttSetup.configuredClrBackground=( ((unsigned int)tempConfiguredClrBackground) << 24); ttSetup.showClock=temp.showClock; ttSetup.suspendReceiving=temp.suspendReceiving; ttSetup.autoUpdatePage=temp.autoUpdatePage; ttSetup.OSDheight=temp.OSDheight; ttSetup.OSDwidth=temp.OSDwidth; ttSetup.OSDHAlign=temp.OSDHAlign; ttSetup.OSDVAlign=temp.OSDVAlign; ttSetup.HideMainMenu=temp.HideMainMenu; //ttSetup.inactivityTimeout=temp.inactivityTimeout; for (int i=0;i> 24)); SetupStore("showClock", ttSetup.showClock); //currently not used //SetupStore("suspendReceiving", ttSetup.suspendReceiving); SetupStore("autoUpdatePage", ttSetup.autoUpdatePage); SetupStore("OSDheight", ttSetup.OSDheight); SetupStore("OSDwidth", ttSetup.OSDwidth); SetupStore("OSDHAlign", ttSetup.OSDHAlign); SetupStore("OSDVAlign", ttSetup.OSDVAlign); SetupStore("HideMainMenu", ttSetup.HideMainMenu); //SetupStore("inactivityTimeout", ttSetup.inactivityTimeout); } cTeletextSetupPage::cTeletextSetupPage(void) { cString buf; cOsdItem *item; //init tables for (int i=0;i= LastAction) {//jump to page selected temp.mapKeyToAction[i]=LastAction; //to display the last string tempPageNumber[i]=ttSetup.mapKeyToAction[i]; } else { //one of the other modes selected temp.mapKeyToAction[i]=ttSetup.mapKeyToAction[i]; tempPageNumber[i]=100; } } tempConfiguredClrBackground=(ttSetup.configuredClrBackground >> 24); temp.showClock=ttSetup.showClock; temp.suspendReceiving=ttSetup.suspendReceiving; temp.autoUpdatePage=ttSetup.autoUpdatePage; temp.OSDheight=ttSetup.OSDheight; temp.OSDwidth=ttSetup.OSDwidth; temp.OSDHAlign=ttSetup.OSDHAlign; temp.OSDVAlign=ttSetup.OSDVAlign; temp.HideMainMenu=ttSetup.HideMainMenu; //temp.inactivityTimeout=ttSetup.inactivityTimeout; Add(new cMenuEditIntItem(tr("Background transparency"), &tempConfiguredClrBackground, 0, 255)); Add(new cMenuEditBoolItem(tr("Show clock"), &temp.showClock )); //Add(new cMenuEditBoolItem(tr("Setup$Suspend receiving"), &temp.suspendReceiving )); Add(new cMenuEditBoolItem(tr("Auto-update pages"), &temp.autoUpdatePage )); Add(new cMenuEditIntItem(tr("OSD height"), &temp.OSDheight, 250, MAXOSDHEIGHT)); Add(new cMenuEditIntItem(tr("OSD width"), &temp.OSDwidth, 320, MAXOSDWIDTH)); Add(new cMenuEditIntItem(tr("OSD horizontal align"), &temp.OSDHAlign, 0, 100)); Add(new cMenuEditIntItem(tr("OSD vertical align"), &temp.OSDVAlign, 0, 100)); Add(new cMenuEditBoolItem(tr("Hide mainmenu entry"), &temp.HideMainMenu)); //Using same string as VDR's setup menu //Add(new cMenuEditIntItem(tr("Setup.Miscellaneous$Min. user inactivity (min)"), &temp.inactivityTimeout)); buf = cString::sprintf("%s:", tr("Key bindings")); item = new cOsdItem(*buf); item->SetSelectable(false); Add(item); for (int i=0;iProcessKey(Key); //if (state != osUnknown) { //really should not return osUnknown I think if (temp.mapKeyToAction[i] == LastAction && !ActionEdits[i].visible) { //need to make it visible if (i+1::Del(ActionEdits[i].number, false); ActionEdits[i].visible=false; Display(); } break; //return state; //} } } return state; //return cMenuSetupPage::ProcessKey(Key); } void ActionEdit::Init(cTeletextSetupPage* s, int num, cMenuEditIntItem *p, cMenuEditStraItem * a) { action=a; number=p; s->Add(action); if (s->temp.mapKeyToAction[num] == LastAction) { s->Add(number); visible=true; } else visible=false; } VDRPLUGINCREATOR(cPluginTeletextosd); // Don't touch this! osdteletext-0.9.4/Makefile0000644000175000017500000000641412117130631015054 0ustar tobiastobias# # Makefile for a Video Disk Recorder plugin # # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. # By default the main source file also carries this name. PLUGIN = osdteletext ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') ### The directory environment: # Use package data if installed...otherwise assume we're under the VDR source directory: PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc)) LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) # TMPDIR ?= /tmp ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) ### The version number of VDR's plugin API: APIVERSION = $(call PKGCFG,apiversion) ### Allow user defined options to overwrite defaults: -include $(PLGCFG) ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) ### The name of the shared object file: SOFILE = libvdr-$(PLUGIN).so ### Includes and Defines (add further entries here): INCLUDES += DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): OBJS = $(PLUGIN).o menu.o txtfont.o txtrecv.o txtrender.o displaybase.o display.o storage.o legacystorage.o packedstorage.o rootdir.o ### The main target: all: $(SOFILE) i18n ### Implicit rules: %.o: %.c $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile @$(MAKEDEP) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ -include $(DEPFILE) ### Internationalization (I18N): PODIR = po I18Npo = $(wildcard $(PODIR)/*.po) I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.c) xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Nmo) $(I18Npot) install-i18n: $(I18Nmsgs) ### Targets: $(SOFILE): $(OBJS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install: install-lib install-i18n dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @tar czf $(PACKAGE).tgz -C $(TMPDIR) --exclude debian --exclude CVS --exclude .svn $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @echo Distribution package created as $(PACKAGE).tgz clean: @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ osdteletext-0.9.4/txtfont.h0000644000175000017500000000065711737124466015316 0ustar tobiastobias// -*- c++ -*- #ifndef __TXTFONT_H #define __TXTFONT_H #include "txtrender.h" unsigned int* GetFontChar(cTeletextChar c, unsigned int *buffer); // Get a character bitmap for character/charset // Also handle double width/height partial characters // buffer must be an unsigned int[10] buffer, that *may* be used // to store the character - a different pointer may be returned too. // returns NULL if undefined character #endif osdteletext-0.9.4/README0000644000175000017500000001223511737124466014312 0ustar tobiastobiasThis is a "plugin" for the Video Disk Recorder (VDR). Written by: Marcel Wiesweg Project's homepage: http://www.wiesweg-online.de/linux/vdr Latest version available at: http://projects.vdr-developer.org/projects/show/plg-osdteletext See the file COPYING for license information. Description: Osd-Teletext displays the teletext directly on the OSD. Both sound and video are played in the background. Keys: 1,...,9: insert page number Up: page+ Down: page- Right: sub page+ Left: sub page- Back: close teletext plugin All other user interaction ("Actions") is configurably assigned to the other available keys. You can e.g. configure that you jump to page 100 when you press Red. In this example, the Action "Jump to 100" is assigned to key "Red". Have a look at the plugin's setup page to learn the current assignment and adapt it to your needs. Available Keys: Blue, Red, Yellow, Green, Play, Stop, FastFwd, FastRwd Actions: "Zoom", "Half page", "Switch channel", "Switch background", "Jump to..." a specific page. Description of the actions: Zoom: Zoom to upper half/lower half/back to full page Half Page: Reduce OSD window to the lower half of the screen and display upper half/lower half/back to full size Switch channel:Show pages of a channel different from the one currently tuned to. This does _not_ include any tuning or channel switching with vdr's core. You must have tuned to the channel chosen some time before so that the pages have been stored on disk. When you press the key associated with that action, you are asked for the channel number. Press OK after you entered it with the number keys. Jump to...: Jumps to the page you configure. Switch background: Toggles background transparency between a value configured in setup, fully black, and fully transparent. How to configure the key bindings: In the plugins setup menu, you can assign one of actions to each key. You can choose freely which actions you need, you are not forced to assign an action to a key at all if you do not need it. If you select "Jump to...", specify the page number in the line immediately below. Other Setup options: Background transparency: number between 0 (transparent) and 255 (black). Default is 127 (also used by VDR) Show Clock: Toggles whether an additional clock is drawn approximately every second. The clock shows the current system time, not any time broadcast via teletext. Let VDR set the system time from a transponder to have the exact time. Auto-update pages: Continuously checks whether a page has changed and updates it if yes. OSD width, OSD height: Adjusts the width and height of the OSD independent from VDR's settings. The valid range is 40 to 56 for the width and 12 to 21 for the height. Minimum user inactivity: Sets a timeout (in minutes) for user inactivity. When this timespan has elapsed and the user did not press any keys, the plugin will be closed. Set to 0 to disable this. Note that disabling timeout will also effectively disable VDR's auto-shutdown feature as long as the plugin is active. Key bindings: See above. Command line options: A few settings are given on the command line rather than in the setup menu. Available options: -d --directory=DIR The directory where the temporary files will be stored. (default: /var/cache/vdr/vtx) Ensure that the directory exists and is writable. -n --max-cache=NUM Maximum size in megabytes of cache used to store the pages on the harddisk. (default: a calculated value below 50 MB) -s --cache-system=SYS Set the cache system to be used. Choose "legacy" for the traditional one-file-per-page system. Default is "packed" for the one-file-for-a-few-pages system. -t --toptext Store top text pages at cache. (unviewable pages) Colors: On all sorts of output devices which are not limited as to color depth the original teletext colors will be displayed. (Only difference: Cyan is used instead of white to make reading easier). On the classic full-featured DVB card and other limited devices, the colors will be reduced to four. The mapping is currently optimized for German ARD, ZDF and RTL. If you are for some reason really and definitely not satisfied with my choices, edit colormapping.h and recompile. osdteletext-0.9.4/pageid.h0000644000175000017500000000214212117130631015010 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __PAGEID_H #define __PAGEID_H #include #include #include #include #include #include struct PageID { PageID() { page=subPage=0; } PageID(tChannelID id, int p, int s) { set(id, p, s); } void set(tChannelID id, int p, int s) { channel=id; page=p; subPage=s; } tChannelID channel; int page; int subPage; }; #endif osdteletext-0.9.4/packedstorage.h0000644000175000017500000000261212117130631016375 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __PACKEDSTORAGE_H #define __PACKEDSTORAGE_H #include "legacystorage.h" class PackedStorage : public LegacyStorage { public: PackedStorage(int maxMB); virtual void getFilename(char *buffer, int bufLength, PageID page); virtual StorageHandle openForWriting(PageID page); virtual StorageHandle openForReading(PageID page, bool countAsAccess); protected: struct PageAddress { bool operator==(const PageID &id) const { return page==id.page && subPage==id.subPage; } void operator=(const PageID &id) { page=id.page; subPage=id.subPage; } int page; int subPage; }; bool seekTo(PageID page, int fd, bool create); void registerFile(PageID page); }; #endif osdteletext-0.9.4/txtrender.c0000644000175000017500000004141711737124466015621 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * txtrender.c - Teletext display abstraction and teletext code * * renderer * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * Changelog: * * 2005-03 initial version (c) Udo Richter * * * ***************************************************************************/ #include #include "txtrender.h" // Font tables // teletext uses 7-bit numbers to identify a font set. // There are three font sets involved: // Primary G0, Secondary G0, and G2 font set. // Font tables are organized in blocks of 8 fonts: enumCharsets FontBlockG0_0000[8] = { CHARSET_LATIN_G0_EN, CHARSET_LATIN_G0_DE, CHARSET_LATIN_G0_SV_FI, CHARSET_LATIN_G0_IT, CHARSET_LATIN_G0_FR, CHARSET_LATIN_G0_PT_ES, CHARSET_LATIN_G0_CZ_SK, CHARSET_LATIN_G0 }; enumCharsets FontBlockG2Latin[8]={ CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2 }; enumCharsets FontBlockG0_0001[8] = { CHARSET_LATIN_G0_PL, CHARSET_LATIN_G0_DE, CHARSET_LATIN_G0_SV_FI, CHARSET_LATIN_G0_IT, CHARSET_LATIN_G0_FR, CHARSET_LATIN_G0, CHARSET_LATIN_G0_CZ_SK, CHARSET_LATIN_G0 }; enumCharsets FontBlockG0_0010[8] = { CHARSET_LATIN_G0_EN, CHARSET_LATIN_G0_DE, CHARSET_LATIN_G0_SV_FI, CHARSET_LATIN_G0_IT, CHARSET_LATIN_G0_FR, CHARSET_LATIN_G0_PT_ES, CHARSET_LATIN_G0_TR, CHARSET_LATIN_G0 }; enumCharsets FontBlockG0_0011[8] = { CHARSET_LATIN_G0, CHARSET_LATIN_G0, CHARSET_LATIN_G0, CHARSET_LATIN_G0, CHARSET_LATIN_G0, CHARSET_LATIN_G0_SR_HR_SL, CHARSET_LATIN_G0, CHARSET_LATIN_G0_RO }; enumCharsets FontBlockG0_0100[8] = { CHARSET_CYRILLIC_G0_SR_HR, CHARSET_LATIN_G0_DE, CHARSET_LATIN_G0_EE, CHARSET_LATIN_G0_LV_LT, CHARSET_CYRILLIC_G0_RU_BG, CHARSET_CYRILLIC_G0_UK, CHARSET_LATIN_G0_CZ_SK, CHARSET_INVALID }; enumCharsets FontBlockG2_0100[8] = { CHARSET_CYRILLIC_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_LATIN_G2, CHARSET_CYRILLIC_G2, CHARSET_CYRILLIC_G2, CHARSET_LATIN_G2, CHARSET_INVALID }; enumCharsets FontBlockG0_0110[8] = { CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_LATIN_G0_TR, CHARSET_GREEK_G0 }; enumCharsets FontBlockG2_0110[8] = { CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_LATIN_G2, CHARSET_GREEK_G2 }; enumCharsets FontBlockG0_1000[8] = { CHARSET_LATIN_G0_EN, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_LATIN_G0_FR, CHARSET_INVALID, CHARSET_INVALID, CHARSET_ARABIC_G0 }; enumCharsets FontBlockG2_1000[8] = { CHARSET_ARABIC_G2, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_ARABIC_G2, CHARSET_INVALID, CHARSET_INVALID, CHARSET_ARABIC_G2 }; enumCharsets FontBlockG0_1010[8] = { CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_HEBREW_G0, CHARSET_INVALID, CHARSET_ARABIC_G0, }; enumCharsets FontBlockG2_1010[8] = { CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_ARABIC_G2, CHARSET_INVALID, CHARSET_ARABIC_G2, }; enumCharsets FontBlockInvalid[8] = { CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID, CHARSET_INVALID }; // The actual font table definition: // Split the 7-bit number into upper 4 and lower 3 bits, // use upper 4 bits for outer array, // use lower 3 bits for inner array struct structFontBlock { enumCharsets *G0Block; enumCharsets *G2Block; }; structFontBlock FontTable[16] = { { FontBlockG0_0000, FontBlockG2Latin }, // 0000 block { FontBlockG0_0001, FontBlockG2Latin }, // 0001 block { FontBlockG0_0010, FontBlockG2Latin }, // 0010 block { FontBlockG0_0011, FontBlockG2Latin }, // 0011 block { FontBlockG0_0100, FontBlockG2_0100 }, // 0100 block { FontBlockInvalid, FontBlockInvalid }, // 0101 block { FontBlockG0_0110, FontBlockG2_0110 }, // 0110 block { FontBlockInvalid, FontBlockInvalid }, // 0111 block { FontBlockG0_1000, FontBlockG2_1000 }, // 1000 block { FontBlockInvalid, FontBlockInvalid }, // 1001 block { FontBlockG0_1010, FontBlockG2_1010 }, // 1010 block { FontBlockInvalid, FontBlockInvalid }, // 1011 block { FontBlockInvalid, FontBlockInvalid }, // 1100 block { FontBlockInvalid, FontBlockInvalid }, // 1101 block { FontBlockInvalid, FontBlockInvalid }, // 1110 block { FontBlockInvalid, FontBlockInvalid } // 1111 block }; inline enumCharsets GetG0Charset(int codepage) { return FontTable[codepage>>3].G0Block[codepage&7]; } inline enumCharsets GetG2Charset(int codepage) { return FontTable[codepage>>3].G2Block[codepage&7]; } cRenderPage::cRenderPage() : Dirty(false), DirtyAll(false), // Todo: make this configurable FirstG0CodePage(0), SecondG0CodePage(0) { } enum enumSizeMode { // Possible size modifications of characters sizeNormal, sizeDoubleWidth, sizeDoubleHeight, sizeDoubleSize }; /* // Debug only: List of teletext spacing code short names const char *(names[0x20])={ "AlBk","AlRd","AlGr","AlYl","AlBl","AlMg","AlCy","AlWh", "Flsh","Stdy","EnBx","StBx","SzNo","SzDh","SzDw","SzDs", "MoBk","MoRd","MoGr","MoYl","MoBl","MoMg","MoCy","MoWh", "Conc","GrCn","GrSp","ESC", "BkBl","StBk","HoMo","ReMo"}; */ void cRenderPage::ReadTeletextHeader(unsigned char *Header) { // Format of buffer: // 0 String "VTXV4" // 5 always 0x01 // 6 magazine number // 7 page number // 8 flags // 9 lang // 10 always 0x00 // 11 always 0x00 // 12 teletext data, 40x24 bytes // Format of flags: // 0x80 C4 - Erase page // 0x40 C5 - News flash // 0x20 C6 - Subtitle // 0x10 C7 - Suppress Header // 0x08 C8 - Update // 0x04 C9 - Interrupt Sequence // 0x02 C9 (Bug?) // 0x01 C11 - Magazine Serial mode Flags=Header[8]; Lang=Header[9]; } void cRenderPage::RenderTeletextCode(unsigned char *PageCode) { int x,y; bool EmptyNextLine=false; // Skip one line, in case double height chars were/will be used // Get code pages: int LocalG0CodePage=(FirstG0CodePage & 0x78) | ((Lang & 0x04)>>2) | (Lang & 0x02) | ((Lang & 0x01)<<2); enumCharsets FirstG0=GetG0Charset(LocalG0CodePage); enumCharsets SecondG0=GetG0Charset(SecondG0CodePage); // Reserved for later use: // enumCharsets FirstG2=GetG2Charset(LocalG0CodePage); for (y=0;y<24;(EmptyNextLine?y+=2:y++)) { // Start of line: Set start of line defaults // Hold Mosaics mode: Remember last mosaic char/charset // for next spacing code bool HoldMosaics=false; unsigned char HoldMosaicChar=' '; enumCharsets HoldMosaicCharset=FirstG0; enumSizeMode Size=sizeNormal; // Font size modification bool SecondCharset=false; // Use primary or secondary G0 charset bool GraphicCharset=false; // Graphics charset used? bool SeparateGraphics=false; // Use separated vs. contiguous graphics charset bool NoNextChar=false; // Skip display of next char, for double-width EmptyNextLine=false; // Skip next line, for double-height cTeletextChar c; // auto.initialized to everything off c.SetFGColor(ttcWhite); c.SetBGColor(ttcBlack); c.SetCharset(FirstG0); if (y==0 && (Flags&0x10)) { c.SetBoxedOut(true); } if (Flags&0x60) { c.SetBoxedOut(true); } // Pre-scan for double-height and double-size codes for (x=0;x<40;x++) { if (y==0 && x<8) x=8; if ((PageCode[x+40*y] & 0x7f)==0x0D || (PageCode[x+40*y] & 0x7f)==0x0F) EmptyNextLine=true; } // Move through line for (x=0;x<40;x++) { unsigned char ttc=PageCode[x+40*y] & 0x7f; // skip parity check if (y==0 && x<8) continue; // no displayable data here... /* // Debug only: Output line data and spacing codes if (y==6) { if (ttc<0x20) printf("%s ",names[ttc]); else printf("%02x ",ttc); if (x==39) printf("\n"); } */ // Handle all 'Set-At' spacing codes switch (ttc) { case 0x09: // Steady c.SetBlink(false); break; case 0x0C: // Normal Size if (Size!=sizeNormal) { Size=sizeNormal; HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } break; case 0x18: // Conceal c.SetConceal(true); break; case 0x19: // Contiguous Mosaic Graphics SeparateGraphics=false; if (GraphicCharset) c.SetCharset(CHARSET_GRAPHICS_G1); break; case 0x1A: // Separated Mosaic Graphics SeparateGraphics=true; if (GraphicCharset) c.SetCharset(CHARSET_GRAPHICS_G1_SEP); break; case 0x1C: // Black Background c.SetBGColor(ttcBlack); break; case 0x1D: // New Background c.SetBGColor(c.GetFGColor()); break; case 0x1E: // Hold Mosaic HoldMosaics=true; break; } // temporary copy of character data: cTeletextChar c2=c; // c2 will be text character or space character or hold mosaic // c2 may also have temporary flags or charsets if (ttc<0x20) { // Spacing code, display space or hold mosaic if (HoldMosaics) { c2.SetChar(HoldMosaicChar); c2.SetCharset(HoldMosaicCharset); } else { c2.SetChar(' '); } } else { // Character code c2.SetChar(ttc); if (GraphicCharset) { if (ttc&0x20) { // real graphics code, remember for HoldMosaics HoldMosaicChar=ttc; HoldMosaicCharset=c.GetCharset(); } else { // invalid code, pass-through to G0 c2.SetCharset(SecondCharset?SecondG0:FirstG0); } } } // Handle double-height and double-width extremes if (y>=23) { if (Size==sizeDoubleHeight) Size=sizeNormal; if (Size==sizeDoubleSize) Size=sizeDoubleWidth; } if (x>=38) { if (Size==sizeDoubleWidth) Size=sizeNormal; if (Size==sizeDoubleSize) Size=sizeDoubleHeight; } // Now set character code if (NoNextChar) { // Suppress this char due to double width last char NoNextChar=false; } else { switch (Size) { case sizeNormal: // Normal sized SetChar(x,y,c2); if (EmptyNextLine && y<23) { // Clean up next line SetChar(x,y+1,c2.ToChar(' ').ToCharset(FirstG0)); } break; case sizeDoubleWidth: // Double width SetChar(x,y,c2.ToDblWidth(dblw_Left)); SetChar(x+1,y,c2.ToDblWidth(dblw_Right)); if (EmptyNextLine && y<23) { // Clean up next line SetChar(x ,y+1,c2.ToChar(' ').ToCharset(FirstG0)); SetChar(x+1,y+1,c2.ToChar(' ').ToCharset(FirstG0)); } NoNextChar=true; break; case sizeDoubleHeight: // Double height SetChar(x,y,c2.ToDblHeight(dblh_Top)); SetChar(x,y+1,c2.ToDblHeight(dblh_Bottom)); break; case sizeDoubleSize: // Double Size SetChar(x , y,c2.ToDblHeight(dblh_Top ).ToDblWidth(dblw_Left )); SetChar(x+1, y,c2.ToDblHeight(dblh_Top ).ToDblWidth(dblw_Right)); SetChar(x ,y+1,c2.ToDblHeight(dblh_Bottom).ToDblWidth(dblw_Left )); SetChar(x+1,y+1,c2.ToDblHeight(dblh_Bottom).ToDblWidth(dblw_Right)); NoNextChar=true; break; } } // Handle all 'Set-After' spacing codes switch (ttc) { case 0x00 ... 0x07: // Set FG color if (GraphicCharset) { // Actual switch from graphics charset HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } c.SetFGColor((enumTeletextColor)ttc); c.SetCharset(SecondCharset?SecondG0:FirstG0); GraphicCharset=false; c.SetConceal(false); break; case 0x08: // Flash c.SetBlink(true); break; case 0x0A: // End Box c.SetBoxedOut(true); break; case 0x0B: // Start Box c.SetBoxedOut(false); break; case 0x0D: // Double Height if (Size!=sizeDoubleHeight) { Size=sizeDoubleHeight; HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } break; case 0x0E: // Double Width if (Size!=sizeDoubleWidth) { Size=sizeDoubleWidth; HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } break; case 0x0F: // Double Size if (Size!=sizeDoubleSize) { Size=sizeDoubleSize; HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } break; case 0x10 ... 0x17: // Mosaic FG Color if (!GraphicCharset) { // Actual switch to graphics charset HoldMosaicChar=' '; HoldMosaicCharset=FirstG0; } c.SetFGColor((enumTeletextColor)(ttc-0x10)); c.SetCharset(SeparateGraphics?CHARSET_GRAPHICS_G1_SEP:CHARSET_GRAPHICS_G1); GraphicCharset=true; c.SetConceal(false); break; case 0x1B: // ESC Switch SecondCharset=!SecondCharset; if (!GraphicCharset) c.SetCharset(SecondCharset?SecondG0:FirstG0); break; case 0x1F: // Release Mosaic HoldMosaics=false; break; } } // end for x } // end for y for (x=0;x<40;x++) { // Clean out last line cTeletextChar c; c.SetFGColor(ttcWhite); c.SetBGColor(ttcBlack); c.SetCharset(FirstG0); c.SetChar(' '); if (Flags&0x60) { c.SetBoxedOut(true); } SetChar(x,24,c); } } osdteletext-0.9.4/README.DE0000644000175000017500000001167711737124466014612 0ustar tobiastobiasBeschreibung: OSD-Teletext zeigt Videotext direkt auf dem OSD an. Im Hintergrund gibt es weiterhin Bild und Ton. Tasten: 1,...,9: Seitenzahl eingeben Hoch: Seite weiter Herunter:Seite zurück Rechts: Unterseite weiter Links: Unterseite zurück Zurück: Videotext-Plugin schließen Die restliche Bedienung ("Aktionen") durch die anderen Tasten ist frei konfigurierbar. Man kann z.B. einstellen, das die man mit der Taste Rot auf die Seite 100 springt. Bei dieser Einstellung wäre die Aktion "Springe zu 100" der Taste Rot zugeordnet. Verfügbare Tasten: Blau, Rot, Gelb, Grün, Play, Stop, Schneller Vorlauf, Schn. Rücklauf Aktionen: "Vergrößern", "Halbe Seite", "Kanal wechseln", "Hintergrund wechseln", "Springe zu..." einer bestimmten Seite Beschreibung der Aktionen: Vergrößern: Obere / untere Hälfte vergrößern / zurück zur ganzen Seite Halbe Seite: OSD-Fenster nur noch in unterer Hälfte des Bildschirms zeigen und obere / untere Hälfte anzeigen bzw. zurück Kanal wechseln:Seiten eines anderen Senders als des gerade eingestellten anzeigen. Dabei wird keine Frequenz gewechselt oder mit VDR ein anderer Kanal eingestellt. Damit Seiten verfügbar sind, muss irgendwann vorher der gewählte Kanal eingestellt gewesen sein. Bei Aufruf der Aktion wird nach der Kanalnummer gefragt. Die Nummer mit den Zifferntasten eingeben und OK drücken. Springe zu...: Springt zu der entsprechenden Seite Hintergrund wechseln: Ändert die im Setup einstellbare Hintergrundfarbe sofort zu Schwarz und nach erneutem Aufruf wieder zurück. Wie man Tasten Aktionen zuordnet: Im Einstellungsmenü des Plugins kann jeder Taste eine Aktion zugeordnet werden. Dabei ist nichts vorgeschrieben - keine Aktion muss irgendeiner Taste zugewiesen werden, wenn sie nicht benötigt wird. Bei Auswahl von "Springe zu..." wird die Seitennummer in der Zeile direkt darunter angegeben. Andere Optionen: Hintergrund-Transparenz: Zahl zwischen 0 (transparent) und 255 (schwarz). Vorgegeben ist 127 (wie auch von VDR) Zeige Uhr: Diese Option bestimmt, ob etwa im Sekundenabstand zusätzlich eine Uhr angezeigt wird. Die Uhr zeigt die aktuelle Systemzeit, nicht die mit dem Videotext ausgestrahlte Zeit. Um genaue Werte zu haben, kann VDR die Systemzeit von einem Transponder einstellen. Automatisch aktualisieren: Überprüft ständig, ob sich die Seite geändert hat und aktualisiert sie wenn nötig OSD-Breite, OSD-Höhe: Hier kann die Breite des OSD unabhängig von den Einstellungen für VDR bestimmt werden. Für die Breite liegt die Zahl zwischen 40 und 56, für die Höhe zwischen 12 und 21. Mindest Benutzer-Inaktivität: Bestimmt die Zeit (in Minuten), nach der das Plugin automatisch geschlossen wird, wenn der Benutzer solange keine Taste betätigt hat. Das kann durch setzen des Wertes auf 0 verhindert werden. Dann wird jedoch auch das automatische Abschalten von VDR effektiv außer Kraft gesetzt, solange das Plugin geöffnet ist. Tasten einrichten: siehe oben Kommandozeilen-Optionen: Einige Einstellungen werden über die Kommandozeile anstatt über das Menü gesetzt. Verfügbare Optionen: -d --directory=DIR Das Verzeichnis für die temporären Dateien. (Voreinstellung: /var/cache/vdr/vtx) Stellen Sie sicher, dass das Verzeichnis existiert und beschreibbar ist. -n --max-cache=NUM Maximale Größe des Zwischenspeichers für Seiten auf der Festplatte. (Voreinstellung: ein berechneter Wert unter 50 MB) -s --cache-system=SYS Das zu benutzende Zwischenspeichersystem. Wählen Sie "legacy" für das althergebrachte System "Eine Datei - eine Seite". Voreinstellung ist "packed" für ein System, das in eine Datei mehrere Seiten speichert. -t --toptext Speichere TopText Seiten (nich anzeigbar) Farben: Auf allen Ausgabegeräten, die nicht in der Farbtiefe des OSD beschränkt sind, werden die unveränderten Farben des Videotexts dargestellt (einzig Weiß wurde zum Zwecke der besseren Lesbarkeit durch Cyan ersetzt). Für die klassische DVB-Karte mit Hardware-Dekoder und anderen so beschränkten Geräten werden nur vier Farben dargestellt. Die Zuordnung ist auf ARD, ZDF und RTL optimiert. Sollten Sie aus irgendeinem Grund absolut nicht meiner Meinung sein, passen Sie die Datei colormapping.h an und kompilieren Sie neu. osdteletext-0.9.4/legacystorage.c0000644000175000017500000001156712117130631016416 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "legacystorage.h" LegacyStorage::LegacyStorage(int maxMB) : fsBlockSize(1), pageBytes(TELETEXT_PAGESIZE) { initMaxStorage(maxMB); } LegacyStorage::~LegacyStorage() { } /* static inline int FilesForMegabytes(double MB, int blocksize) { double pageBytes; if (TELETEXT_PAGESIZE<=blocksize) pageBytes=blocksize; else pageBytes=((TELETEXT_PAGESIZE/blocksize)+1)*blocksize; //reserve 10% for directories return (int)( (1024.0 * 1024.0 * (MB-MB*0.1)) / pageBytes ); }*/ int LegacyStorage::actualFileSize(int netFileSize) { if (netFileSize<=0) return 0; if (netFileSize<=fsBlockSize) return fsBlockSize; else return ((netFileSize/fsBlockSize)+1)*fsBlockSize; } //max==0 means unlimited, max==-1 means a reasonable default value shall be calculated void LegacyStorage::initMaxStorage(int maxMB) { struct statfs fs; if (statfs(getRootDir(), &fs)!=0) { esyslog("OSD-Teletext: Error statfs'ing root directory \"%s\": %s, cache size uncontrolled", getRootDir(), strerror(errno)); return; } fsBlockSize=fs.f_bsize; pageBytes=actualFileSize(TELETEXT_PAGESIZE); if (maxMB>=0) { if (maxMB<3) { esyslog("OSD-Teletext: Request to use at most %d MB for caching. This is not enough, using 3 MB", maxMB); maxMB=3; } maxBytes=MEGABYTE(maxMB); } else if (maxMB==-1) { //calculate a default value double blocksPerMeg = 1024.0 * 1024.0 / fs.f_bsize; double capacityMB=fs.f_blocks / blocksPerMeg; double freeMB=(fs.f_bavail / blocksPerMeg); if (capacityMB<=50 || freeMB<50) { //small (<=50MB) filesystems as root dir are assumed to be dedicated for use as a teletext cache //for others, the maximum default size is set to 50 MB maxBytes=MEGABYTE((int)freeMB); //maxPages= FilesForMegabytes(freeMB, fs.f_bsize); if (freeMB<3.0) { esyslog("OSD-Teletext: Less than %.1f MB free on filesystem of root directory \"%s\"!", freeMB, getRootDir()); maxBytes=MEGABYTE(3); } } else { //the maximum default size is set to 50 MB maxBytes=MEGABYTE(50); } //printf("Set maxBytes to %ld, %.2f %.2f\n", maxBytes, capacityMB, freeMB); } } void LegacyStorage::cleanUp() { byteCount -= Storage::doCleanUp(); } void LegacyStorage::registerFile(PageID page) { //pageBytes is already effective size if ( maxBytes && (byteCount+=pageBytes)>maxBytes ) freeSpace(); } StorageHandle LegacyStorage::openForReading(PageID page, bool countAsAccess) { //the countAsAccess argument was intended for use in a LRU cache, currently unused char filename[PATH_MAX]; getFilename(filename, sizeof(filename), page); StorageHandle ret=(StorageHandle)open(filename, O_RDONLY); return ret; } StorageHandle LegacyStorage::openForWriting(PageID page) { static bool wroteError=false; char filename[PATH_MAX]; getFilename(filename, sizeof(filename), page); bool existed=exists(filename); //first try StorageHandle fd=(StorageHandle)open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd) { if (!existed) registerFile(page); return fd; } //no space on disk? make some space available if (errno == ENOSPC) freeSpace(); //second try fd=(StorageHandle)open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (!fd && !wroteError) { //report error to syslog - once! wroteError=true; esyslog("OSD-Teletext: Error opening teletext file %s: %s", filename, strerror(errno)); } //make sure newly created files are counted if (fd && !existed) registerFile(page); return fd; } ssize_t LegacyStorage::write(const void *ptr, size_t size, StorageHandle stream) { ssize_t written; if (!(written=::write((int)stream, ptr, size)) ) { switch (errno) { case ENOSPC: freeSpace(); return ::write((int)stream, ptr, size); case EINTR: esyslog("OSD-Teletext: EINTR while writing. Please contact the author and tell him this happened."); break; default: break; } } return written; } osdteletext-0.9.4/displaybase.h0000644000175000017500000002002311737124466016075 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * displaybase.h - Base class for rendering a teletext cRenderPage to * * an actual VDR OSD. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * Changelog: * * 2005-03 initial version (c) Udo Richter * * * ***************************************************************************/ #ifndef OSDTELETEXT_DISPLAYBASE_H_ #define OSDTELETEXT_DISPLAYBASE_H_ #include "txtrender.h" #include class cDisplay : public cRenderPage { // Class that extends the virtual cRenderPage with the capability // to render its contents to an OSD of variable size. // Renders incrementally - just changes // plus adds some more display features like message display. public: enum enumZoom { // Zoom up upper/lower half of page Zoom_Off, Zoom_Upper, Zoom_Lower } Zoom; protected: bool Concealed; // Hidden text internal state bool Blinked; // Blinking text internal state int FlushLock; // Lock counter for bundeling OSD flushes bool Boxed; // Page is 'boxed mode' transparent int Width; int Height; // OSD pixel dimension tColor Background; // Color to be used for black background // - allow transparency cOsd *osd; // The osd object. If creation fails, may be NULL int ScaleX,ScaleY; int OffsetX,OffsetY; // Virtual coordinate system, see InitScaler const cFont *MessageFont; int MessageX,MessageY,MessageW,MessageH; // Message overlay window, position and font class cBox { // helper class. Represents a character's box in virtual coordinates public: int XMin,YMin,XMax,YMax; inline void SetToCharacter(int x, int y); }; friend class cBox; class cVirtualCoordinate { // helper class. Represents a coordinate in virtual display space // and in OSD pixel coordinates. public: int OsdX,OsdY; int VirtX,VirtY; inline void VirtualToPixel(cDisplay *Display, int x, int y); inline void IncPixelX(cDisplay *Display); inline void IncPixelY(cDisplay *Display); }; friend class cVirtualCoordinate; public: cDisplay(int width, int height); virtual ~cDisplay(); bool Valid() { return (osd!=NULL); } // After creation, check for Valid(). Destroy, if not valid. protected: void InitScaler(); // Initialize transformation for OSD->Virtual coordinates // Some words about scaling: // OSD display is variable width x height, with 3 pixels border // on all sides. There is a virtual coordinate system projected // on this, with (3,3) mapped to (0,0) and (width-3,height-3) // mapped to (480<<16,250<<16). // The idea is, that each font pixel uses a virtual rectangle // of (1<<16,1<<16) size. // ScaleX,ScaleY represent the (virtual) width and height of a // physical OSD pixel. // OffsetX,OffsetY default to 3,3 to represent the border offset, // but may be used differently. public: bool GetBlink() { return Blinked; } bool SetBlink(bool blink); // Switch blink frequently to get blinking chars // Returns true if there are blinking characters. bool GetConceal() { return Concealed; } bool SetConceal(bool conceal); // Hidden text. Set to true to see hidden text. // Returns true if there are concealed characters. enumZoom GetZoom() { return Zoom; } void SetZoom(enumZoom zoom); // Zoom to upper/lower half of page void SetBackgroundColor(tColor c); tColor GetBackgroundColor() { return Background; } // Set the background color for black. Allows transparent black. // Color mapping interface. virtual tColor GetColorRGB(enumTeletextColor ttc, int Area); // Map a teletext color to an OSD color in #Area. virtual tColor GetColorRGBAlternate(enumTeletextColor ttc, int Area); // For color collision: // Map this teletext color to an OSD color in #Area, but dont // return same as GetColorRGB(). Used to solve conflicts if // foreground and background are mapped to same color. // Defaults to 1:1 identity. Not needed if all colors actually // supported by OSD. int GetColorIndex(enumTeletextColor ttc, int Area) { // Map this teletext color to an OSD color index in #Area. if (!osd) return 0; cBitmap *bm=osd->GetBitmap(Area); if (!bm) return 0; return bm->Index(GetColorRGB(ttc,Area)); } int GetColorIndexAlternate(enumTeletextColor ttc, int Area) { // Map this teletext color to an OSD color index in #Area. if (!osd) return 0; cBitmap *bm=osd->GetBitmap(Area); if (!bm) return 0; return bm->Index(GetColorRGBAlternate(ttc,Area)); } protected: void InitPalette(); // Initialize palette(s) for OSD void DrawDisplay(); // Draw all dirty characters from cRenderPage buffer to OSD void CleanDisplay(); // Clean OSD completely virtual void DrawChar(int x, int y, cTeletextChar c); // Draw a single character to OSD public: void HoldFlush() { FlushLock++; } // Hold all OSD flush updates to bundle operations. void ReleaseFlush() { FlushLock--; Flush(); } // Release hold of flush updates. After last release, // the flush will be done protected: void Flush() { // Commit all changes from OSD internal bitmaps to device // All draw operations inside cDisplay should call it, // no one outside should need to call it. if (FlushLock>0) return; if (!osd) return; if (IsDirty()) DrawDisplay(); osd->Flush(); } public: void RenderTeletextCode(unsigned char *PageCode); // Interprete teletext code referenced by PageCode // and draw the whole page content into OSD. // PageCode must be a 40*24+12 bytes buffer void DrawText(int x, int y, const char *text, int len); // Draw some characters in teletext page. // Max len chars, fill up with spaces void DrawClock(); // Draw current time to OSD void DrawPageId(const char *text) { DrawText(0,0,text,8); } // Draw Page ID string to OSD void DrawMessage(const char *txt); // Draw a framed, centered message box to OSD void ClearMessage(); // Remove message box and redraw hidden content }; inline void cDisplay::cBox::SetToCharacter(int x, int y) { // Virtual box area of a character XMin=(x*12)<<16; YMin=(y*10)<<16; XMax=XMin+(12<<16)-1; YMax=YMin+(10<<16)-1; } inline void cDisplay::cVirtualCoordinate::VirtualToPixel(cDisplay *Display, int x, int y) { // Map virtual coordinate to OSD pixel OsdX=x/Display->ScaleX+Display->OffsetX; OsdY=y/Display->ScaleY+Display->OffsetY; // map OSD pixel back to virtual coordinate, use center of pixel VirtX=(OsdX-Display->OffsetX)*Display->ScaleX+Display->ScaleX/2; VirtY=(OsdY-Display->OffsetY)*Display->ScaleY+Display->ScaleY/2; } inline void cDisplay::cVirtualCoordinate::IncPixelX(cDisplay *Display) { // Move one OSD pixel OsdX++; VirtX+=Display->ScaleX; } inline void cDisplay::cVirtualCoordinate::IncPixelY(cDisplay *Display) { // Move one OSD pixel OsdY++; VirtY+=Display->ScaleY; } #endif osdteletext-0.9.4/packedstorage.c0000644000175000017500000001122212117130631016365 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "packedstorage.h" PackedStorage::PackedStorage(int maxMB) : LegacyStorage(maxMB) { } #define TOC_SIZE 8 //The file structure is simple: // TOC_SIZE*PageAddress contains the numbers of the following pages // TOC_SIZE*TELETEXT_PAGESIZE contains the page data //and the same again. bool PackedStorage::seekTo(PageID page, int desc, bool create) { lseek(desc, 0, SEEK_SET); PageAddress addr[TOC_SIZE]; while (::read(desc, addr, sizeof(addr)) == sizeof(addr)) { lseek(desc, 0, SEEK_CUR); for (int index=0; indexmaxBytes ) freeSpace(); return (StorageHandle)desc; } //no space on disk? make some space available if (errno == ENOSPC) freeSpace(); //second try desc=open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (desc==-1 && !wroteError) { //report error to syslog - once! wroteError=true; esyslog("OSD-Teletext: Error opening teletext file %s: %s", filename, strerror(errno)); } if (desc==-1) return StorageHandle(); else if (!seekTo(page, desc, true)) { ::close(desc); return StorageHandle(); } if ( maxBytes && byteCount>maxBytes ) freeSpace(); return (StorageHandle)desc; } StorageHandle PackedStorage::openForReading(PageID page, bool countAsAccess) { int desc; if ( (desc=(int)LegacyStorage::openForReading(page, false))!= -1 ) { if (!seekTo(page, desc, false)) { //this is not an error condition here, may and shall happen! ::close(desc); } else { return (StorageHandle)desc; } } return StorageHandle(); } osdteletext-0.9.4/txtrecv.h0000644000175000017500000000433012117130631015257 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __TXTRECV_H #define __TXTRECV_H #include #include #include #include #include #include #include "storage.h" class cTelePage { private: int mag; unsigned char flags; unsigned char lang; PageID page; unsigned char pagebuf[27*40]; Storage* storage; public: cTelePage(PageID page, uchar flags, uchar lang, int mag, Storage *s); ~cTelePage(); void SetLine(int, uchar*); void save(); bool IsTopTextPage(); }; class cRingTxtFrames : public cRingBufferFrame { public: cRingTxtFrames(int Size) : cRingBufferFrame(Size, true) {}; ~cRingTxtFrames() { Clear(); }; void Wait(void) { WaitForGet(); }; void Signal(void) { EnableGet(); }; }; class cTxtReceiver : public cReceiver, public cThread { private: void DecodeTXT(uchar*); uchar unham16 (uchar*); cTelePage *TxtPage; void SaveAndDeleteTxtPage(); bool storeTopText; cRingTxtFrames buffer; Storage *storage; protected: virtual void Activate(bool On); virtual void Receive(uchar *Data, int Length); virtual void Action(); public: cTxtReceiver(const cChannel* chan, bool storeTopText, Storage* storage); virtual ~cTxtReceiver(); virtual void Stop(); }; class cTxtStatus : public cStatus { private: cTxtReceiver *receiver; bool storeTopText; Storage* storage; protected: virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView); public: cTxtStatus(bool storeTopText, Storage* storage); ~cTxtStatus(); }; #endif osdteletext-0.9.4/COPYING0000644000175000017500000004310311737124466014463 0ustar tobiastobias GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. osdteletext-0.9.4/setup.h0000644000175000017500000000310211737124466014734 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __SETUP_H #define __SETUP_H //There are two places to be kept in sync with these enums: //TeletextBrowser::TranslateKey and //the constants in cPluginTeletextosd::initTexts enum eTeletextAction { Zoom, HalfPage, SwitchChannel, DarkScreen, /*SuspendReceiving,*/ LastAction }; //and 100-899 => jump to page enum ActionKeys { ActionKeyRed, ActionKeyGreen, ActionKeyYellow, ActionKeyBlue, ActionKeyPlay, ActionKeyStop, ActionKeyFastFwd, ActionKeyFastRew, LastActionKey }; //Default values are set in menu.c, setup menu, parsing and storing can be found in osdteletext.c class TeletextSetup { public: TeletextSetup(); int mapKeyToAction[10]; //4 color keys + kPlay, kPause etc. unsigned int configuredClrBackground; int showClock; int suspendReceiving; int autoUpdatePage; int OSDheight; int OSDwidth; int OSDHAlign; int OSDVAlign; int inactivityTimeout; int HideMainMenu; }; extern TeletextSetup ttSetup; #endif osdteletext-0.9.4/legacystorage.h0000644000175000017500000000277112117130631016420 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __LEGACYSTORAGE_H #define __LEGACYSTORAGE_H #include "storage.h" class LegacyStorage : public Storage { private: void initMaxStorage(int maxMB=-1); public: LegacyStorage(int maxMB); virtual ~LegacyStorage(); virtual void cleanUp(); virtual StorageHandle openForWriting(PageID page); virtual StorageHandle openForReading(PageID page, bool countAsAccess); virtual ssize_t write(const void *ptr, size_t size, StorageHandle stream); virtual ssize_t read(void *ptr, size_t size, StorageHandle stream) { return ::read((int)stream, ptr, size); } virtual void close(StorageHandle stream) { ::close((int)stream); } protected: void registerFile(PageID page); virtual int actualFileSize(int netFileSize); //int maxPages; long maxBytes; int fsBlockSize; int pageBytes; }; #endif osdteletext-0.9.4/txtrender.h0000644000175000017500000002725012116726264015621 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * txtrender.h - Teletext display abstraction and teletext code * * renderer * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * Changelog: * * 2005-03 initial version (c) Udo Richter * * * ***************************************************************************/ #ifndef OSDTELETEXT_TXTRENDER_H_ #define OSDTELETEXT_TXTRENDER_H_ #include // Teletext character sets enum enumCharsets { CHARSET_LATIN_G0 = 0x0000, // native latin (partially todo) CHARSET_LATIN_G0_CZ_SK = 0x0100, // Czech/Slovak (todo) CHARSET_LATIN_G0_EN = 0x0200, // English CHARSET_LATIN_G0_EE = 0x0300, // Estonian (todo) CHARSET_LATIN_G0_FR = 0x0400, // French CHARSET_LATIN_G0_DE = 0x0500, // German CHARSET_LATIN_G0_IT = 0x0600, // Italian CHARSET_LATIN_G0_LV_LT = 0x0700, // Lettish/Lithuanian (todo) CHARSET_LATIN_G0_PL = 0x0800, // Polish (todo) CHARSET_LATIN_G0_PT_ES = 0x0900, // Portuguese/Spanish CHARSET_LATIN_G0_RO = 0x0A00, // Romanian (todo) CHARSET_LATIN_G0_SR_HR_SL = 0x0B00, // Serbian/Croatian/Slovenian (todo) CHARSET_LATIN_G0_SV_FI = 0x0C00, // Swedish/Finnish CHARSET_LATIN_G0_TR = 0x0D00, // Turkish (todo) CHARSET_LATIN_G2 = 0x0E00, // Latin G2 supplementary set (todo) CHARSET_CYRILLIC_G0_SR_HR = 0x0F00, // Serbian/Croatian (todo) CHARSET_CYRILLIC_G0_RU_BG = 0x1000, // Russian/Bulgarian (todo) CHARSET_CYRILLIC_G0_UK = 0x1100, // Ukrainian (todo) CHARSET_CYRILLIC_G2 = 0x1200, // Cyrillic G2 Supplementary (todo) CHARSET_GREEK_G0 = 0x1300, // Greek G0 (todo) CHARSET_GREEK_G2 = 0x1400, // Greeek G2 (todo) CHARSET_ARABIC_G0 = 0x1500, // Arabic G0 (todo) CHARSET_ARABIC_G2 = 0x1600, // Arabic G2 (todo) CHARSET_HEBREW_G0 = 0x1700, // Hebrew G0 (todo) CHARSET_GRAPHICS_G1 = 0x1800, // G1 graphics set CHARSET_GRAPHICS_G1_SEP = 0x1900, // G1 graphics set, separated CHARSET_GRAPHICS_G3 = 0x1A00, // G3 graphics set (todo) CHARSET_INVALID = 0x1F00 // no charset defined }; // Macro to get the lowest non-0 bit position from a bit mask // Should evaluate to const on a const mask #define LowestSet2Bit(mask) ((mask)&0x0001?0:1) #define LowestSet4Bit(mask) ((mask)&0x0003?LowestSet2Bit(mask):LowestSet2Bit((mask)>>2)+2) #define LowestSet8Bit(mask) ((mask)&0x000f?LowestSet4Bit(mask):LowestSet4Bit((mask)>>4)+4) #define LowestSet16Bit(mask) ((mask)&0x00ff?LowestSet8Bit(mask):LowestSet8Bit((mask)>>8)+8) #define LowestSet32Bit(mask) ((mask)&0xffff?LowestSet16Bit(mask):LowestSet16Bit((mask)>>16)+16) // Character modifcation double height: enum enumDblHeight { dblh_Normal=0x00000000, // normal height dblh_Top =0x04000000, // upper half character dblh_Bottom=0x08000000 // lower half character }; // Character modifcation double width: enum enumDblWidth { dblw_Normal=0x00000000, // normal width dblw_Left =0x10000000, // left half character dblw_Right =0x20000000 // right half character }; // Teletext colors enum enumTeletextColor { // level 1: ttcBlack=0, ttcRed=1, ttcGreen=2, ttcYellow=3, ttcBlue=4, ttcMagenta=5, ttcCyan=6, ttcWhite=7, // level 2.5: ttcTransparent=8, ttcHalfRed=9, ttcHalfGreen=10, ttcHalfYellow=11, ttcHalfBlue=12, ttcHalfMagenta=13, ttcHalfCyan=14, ttcGrey=15, // unnamed, level 2.5: ttcColor16=16, ttcColor17=17, ttcColor18=18, ttcColor19=19, ttcColor20=20, ttcColor21=21, ttcColor22=22, ttcColor23=23, ttcColor24=24, ttcColor25=25, ttcColor26=26, ttcColor27=27, ttcColor28=28, ttcColor29=29, ttcColor30=30, ttcColor31=31, ttcFirst=0, ttcLast=31 }; inline enumTeletextColor& operator++(enumTeletextColor& c) { return c=enumTeletextColor(int(c)+1); } inline enumTeletextColor operator++(enumTeletextColor& c, int) { enumTeletextColor tmp(c); ++c; return tmp; } class cTeletextChar { // Wrapper class that represents a teletext character, // including colors and effects. Should optimize back // to 4 byte unsigned int on compile. protected: unsigned int c; static const unsigned int CHAR = 0x000000FF; // character code static const unsigned int CHARSET = 0x00001F00; // character set code, see below static const unsigned int BOXOUT = 0x00004000; // 'boxed' mode hidden area static const unsigned int DIRTY = 0x00008000; // 'dirty' bit - internal marker only static const unsigned int FGCOLOR = 0x001F0000; // 5-bit foreground color code, 3 bit used for now static const unsigned int BGCOLOR = 0x03E00000; // 5-bit background color code, 3 bit used for now static const unsigned int DBLHEIGHT = 0x0C000000; // show double height static const unsigned int DBLWIDTH = 0x30000000; // show double width (todo) static const unsigned int CONCEAL = 0x40000000; // character concealed static const unsigned int BLINK = 0x80000000; // blinking character cTeletextChar(unsigned int cc) { c=cc; } public: cTeletextChar() { c=0; } // inline helper functions: // For each parameter encoded into the 32-bit int, there is // a Get...() to read, a Set...() to write, and a To...() to // return a modified copy inline unsigned char GetChar() { return c&CHAR; } inline void SetChar(unsigned char chr) { c=(c&~CHAR)|chr; } inline cTeletextChar ToChar(unsigned char chr) { return cTeletextChar((c&~CHAR)|chr); } inline enumCharsets GetCharset() { return (enumCharsets)(c&CHARSET); } inline void SetCharset(enumCharsets charset) { c=(c&~CHARSET)|charset; } inline cTeletextChar ToCharset(enumCharsets charset) { return cTeletextChar((c&~CHARSET)|charset); } inline enumTeletextColor GetFGColor() { return (enumTeletextColor)((c&FGCOLOR) >> LowestSet32Bit(FGCOLOR)); } inline void SetFGColor(enumTeletextColor fgc) { c=(c&~FGCOLOR) | (fgc << LowestSet32Bit(FGCOLOR)); } inline cTeletextChar ToFGColor(enumTeletextColor fgc) { return cTeletextChar((c&~FGCOLOR) | (fgc << LowestSet32Bit(FGCOLOR))); } inline enumTeletextColor GetBGColor() { return (enumTeletextColor)((c&BGCOLOR) >> LowestSet32Bit(BGCOLOR)); } inline void SetBGColor(enumTeletextColor bgc) { c=(c&~BGCOLOR) | (bgc << LowestSet32Bit(BGCOLOR)); } inline cTeletextChar ToBGColor(enumTeletextColor bgc) { return cTeletextChar((c&~BGCOLOR) | (bgc << LowestSet32Bit(BGCOLOR))); } inline bool GetBoxedOut() { return c&BOXOUT; } inline void SetBoxedOut(bool BoxedOut) { c=(BoxedOut)?(c|BOXOUT):(c&~BOXOUT); } inline cTeletextChar ToBoxedOut(bool BoxedOut) { return cTeletextChar((BoxedOut)?(c|BOXOUT):(c&~BOXOUT)); } inline bool GetDirty() { return c&DIRTY; } inline void SetDirty(bool Dirty) { c=(Dirty)?(c|DIRTY):(c&~DIRTY); } inline cTeletextChar ToDirty(bool Dirty) { return cTeletextChar((Dirty)?(c|DIRTY):(c&~DIRTY)); } inline enumDblHeight GetDblHeight() { return (enumDblHeight)(c&DBLHEIGHT); } inline void SetDblHeight(enumDblHeight dh) { c=(c&~(DBLHEIGHT)) | dh; } inline cTeletextChar ToDblHeight(enumDblHeight dh) { return cTeletextChar((c&~(DBLHEIGHT)) | dh); } inline enumDblWidth GetDblWidth() { return (enumDblWidth)(c&DBLWIDTH); } inline void SetDblWidth(enumDblWidth dw) { c=(c&~(DBLWIDTH)) | dw; } inline cTeletextChar ToDblWidth(enumDblWidth dw) { return cTeletextChar((c&~(DBLWIDTH)) | dw); } inline bool GetConceal() { return c&CONCEAL; } inline void SetConceal(bool Conceal) { c=(Conceal)?(c|CONCEAL):(c&~CONCEAL); } inline cTeletextChar ToConceal(bool Conceal) { return cTeletextChar((Conceal)?(c|CONCEAL):(c&~CONCEAL)); } inline bool GetBlink() { return c&BLINK; } inline void SetBlink(bool Blink) { c=(Blink)?(c|BLINK):(c&~BLINK); } inline cTeletextChar ToBlink(bool Blink) { return cTeletextChar((Blink)?(c|BLINK):(c&~BLINK)); } bool operator==(cTeletextChar &chr) { return c==chr.c; } bool operator!=(cTeletextChar &chr) { return c!=chr.c; } }; class cRenderPage { // Abstraction of a 40x25 teletext character page // with all special attributes and colors // Additionally tracks changes by maintaining a // 'dirty' flag on each character protected: cTeletextChar Page[40][25]; int Flags; // 0x80 C4 - Erase page // 0x40 C5 - News flash // 0x20 C6 - Subtitle // 0x10 C7 - Suppress Header // 0x08 C8 - Update // 0x04 C9 - Interrupt Sequence // 0x02 C10 - Inhibit Display // 0x01 C11 - Magazine Serial mode int Lang; // 3-bit language number from header bool Dirty; // At least one character is dirty bool DirtyAll; // Consider all characters dirty, regardless of flag // Font Code pages int FirstG0CodePage; // 7-bit number, lower 3 bits ignored int SecondG0CodePage; // 7-bit number public: cRenderPage(); cTeletextChar GetChar(int x, int y) { // Read character content from page if (x<0 || x>=40 || y<0 || y>=25) { printf("Warning: out of bounds read access to teletext page\n"); return cTeletextChar(); } return Page[x][y].ToDirty(false); } bool IsDirty() { // global dirty status return Dirty; } bool IsDirty(int x, int y) { // local dirty status if (x<0 || x>=40 || y<0 || y>=25) { printf("Warning: out of bounds read access to teletext page\n"); return false; } return Page[x][y].GetDirty() | DirtyAll; } void MakeDirty(int x, int y) { // force one character dirty if (x<0 || x>=40 || y<0 || y>=25) { printf("Warning: out of bounds write access to teletext page\n"); return; } Page[x][y].SetDirty(true); Dirty=true; } void SetChar(int x, int y, cTeletextChar c) { // Set character at given location if (x<0 || x>=40 || y<0 || y>=25) { printf("Warning: out of bounds write access to teletext page\n"); return; } if (GetChar(x,y) != c) { Page[x][y]=c.ToDirty(true); Dirty=true; } } void ReadTeletextHeader(unsigned char *Header); // Read header from teletext page // Header must be a 12 bytes buffer void RenderTeletextCode(unsigned char *PageCode); // Interprete teletext code referenced by PageCode // and draw the whole page content into this object // PageCode must be a 40*24 bytes buffer }; #endif osdteletext-0.9.4/po/0000755000175000017500000000000012117131615014030 5ustar tobiastobiasosdteletext-0.9.4/po/ca_ES.po0000644000175000017500000000312012117131615015336 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Marc Rovira Vall , 2003 # Ramon Roca , 2003 # Jordi Vilà , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-05-04 15:33+0200\n" "Last-Translator: Jordi Vilà \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Canal (premi OK):" msgid "Page" msgstr "Pàgina" msgid "not found" msgstr "no trobada" msgid "Displays teletext on the OSD" msgstr "Visualitza el teletext en l'OSD" msgid "Teletext" msgstr "Teletext" msgid "Zoom" msgstr "Zoom" msgid "Half page" msgstr "Mitja pàgina" msgid "Change channel" msgstr "Canvi cadena" msgid "Switch background" msgstr "Canvia el fons" msgid "Jump to..." msgstr "Salta a..." msgid "Background transparency" msgstr "Transparència del fons" msgid "Show clock" msgstr "Visualitza l'hora" msgid "Auto-update pages" msgstr "Actualització pàgines automàtica" msgid "OSD height" msgstr "Altura OSD" msgid "OSD width" msgstr "Amplària OSD" msgid "OSD horizontal align" msgstr "" msgid "OSD vertical align" msgstr "" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "" msgid " Page number" msgstr " Nombre de pàgina" osdteletext-0.9.4/po/es_ES.po0000644000175000017500000000277512117131615015401 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Ruben Nunez Francisco , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-05-04 15:33+0200\n" "Last-Translator: Ruben Nunez Francisco \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Canal (pulse OK):" msgid "Page" msgstr "Página" msgid "not found" msgstr "no encontrada" msgid "Displays teletext on the OSD" msgstr "Visualiza el teletexto en el OSD" msgid "Teletext" msgstr "Teletexto" msgid "Zoom" msgstr "Zoom" msgid "Half page" msgstr "Media página" msgid "Change channel" msgstr "Cambio cadena" msgid "Switch background" msgstr "Cambia el fondo" msgid "Jump to..." msgstr "Salta a..." msgid "Background transparency" msgstr "Transparencia del fondo" msgid "Show clock" msgstr "Visualiza el reloj" msgid "Auto-update pages" msgstr "" msgid "OSD height" msgstr "Altura OSD" msgid "OSD width" msgstr "Anchura OSD" msgid "OSD horizontal align" msgstr "" msgid "OSD vertical align" msgstr "" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "" msgid " Page number" msgstr " Número de página" osdteletext-0.9.4/po/ru_RU.po0000644000175000017500000000347312117131615015433 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Vyacheslav Dikonov , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-12-30 13:52+0100\n" "Last-Translator: Oleg Roitburd \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Канал (Нажмите ОК)" msgid "Page" msgstr "Страница" msgid "not found" msgstr "не найдена" msgid "Displays teletext on the OSD" msgstr "Показ телетекста в OSD" #, fuzzy msgid "Teletext" msgstr "Телетекст" msgid "Zoom" msgstr "увеличить" msgid "Half page" msgstr "пол-страницы" msgid "Change channel" msgstr "переключить канал" msgid "Switch background" msgstr "Переключить фон" msgid "Jump to..." msgstr "перейти к..." msgid "Background transparency" msgstr "Прозрачность фона" msgid "Show clock" msgstr "Показывать часы" msgid "Auto-update pages" msgstr "Автообновление страниц" msgid "OSD height" msgstr "Высота меню" msgid "OSD width" msgstr "Ширина меню" msgid "OSD horizontal align" msgstr "Горизонтальное положение OSD" msgid "OSD vertical align" msgstr "Вертикальное положение OSD" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "Привязка кнопок" msgid " Page number" msgstr " Номер страницы" osdteletext-0.9.4/po/fi_FI.po0000644000175000017500000000305012117131615015342 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Rolf Ahrenberg , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-05-04 15:33+0200\n" "Last-Translator: Rolf Ahrenberg \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Kanava (paina OK):" msgid "Page" msgstr "Sivua" msgid "not found" msgstr "ei löydy" msgid "Displays teletext on the OSD" msgstr "Teksti-TV (OSD)" msgid "Teletext" msgstr "Teksti-TV" msgid "Zoom" msgstr "Suurenna" msgid "Half page" msgstr "Puolikas sivu" msgid "Change channel" msgstr "Vaihda kanavaa" msgid "Switch background" msgstr "Vaihda tausta" msgid "Jump to..." msgstr "Siirry sivulle..." msgid "Background transparency" msgstr "Taustan läpinäkyvyys" msgid "Show clock" msgstr "Näytä kello" msgid "Auto-update pages" msgstr "Automaattinen sivupäivitys" msgid "OSD height" msgstr "Korkeus" msgid "OSD width" msgstr "Leveys" msgid "OSD horizontal align" msgstr "Pystykeskitys" msgid "OSD vertical align" msgstr "Vaakakeskitys" msgid "Hide mainmenu entry" msgstr "Piilota valinta päävalikosta" msgid "Key bindings" msgstr "Näppäintoiminnot" msgid " Page number" msgstr " Sivunumero" osdteletext-0.9.4/po/uk_UA.po0000644000175000017500000000353512117131615015402 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Yarema P. aka Knedlyk , 2008 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2009-05-25 20:33+0200\n" "Last-Translator: Yarema P. aka Knedlyk \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Канал (натисніть ОК): " msgid "Page" msgstr "Сторінка" msgid "not found" msgstr "не знайдена" msgid "Displays teletext on the OSD" msgstr "Показувати телетекст в меню" msgid "Teletext" msgstr "Телетекст" msgid "Zoom" msgstr "Збільшити" msgid "Half page" msgstr "Пів сторінки" msgid "Change channel" msgstr "Змінити канал" msgid "Switch background" msgstr "Переключити фон" msgid "Jump to..." msgstr "Перейти до..." msgid "Background transparency" msgstr "Ступінь прозорості фону" msgid "Show clock" msgstr "Показувати годинник" msgid "Auto-update pages" msgstr "Автооновлення сторінок" msgid "OSD height" msgstr "Висота OSD" msgid "OSD width" msgstr "Ширина OSD" msgid "OSD horizontal align" msgstr "Горизонтальне положення OSD" msgid "OSD vertical align" msgstr "Вертикальне положення OSD" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "Призначення клавіш" msgid " Page number" msgstr " Номер сторінки" osdteletext-0.9.4/po/it_IT.po0000644000175000017500000000354512117131615015407 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Alberto Carraro , 2001 # Antonio Ospite , 2003 # Sean Carlos , 2005 # Davide Cavalca , 2008 # Diego Pierotto , 2008 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2010-11-06 19:59+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Italian\n" "X-Poedit-Country: ITALY\n" "X-Poedit-SourceCharset: utf-8\n" msgid "Channel (press OK): " msgstr "Canale (premi OK): " msgid "Page" msgstr "Pagina" msgid "not found" msgstr "non trovata" msgid "Displays teletext on the OSD" msgstr "Mostra il teletext in OSD" msgid "Teletext" msgstr "Teletext" msgid "Zoom" msgstr "Ingrandisci" msgid "Half page" msgstr "Metà pagina" msgid "Change channel" msgstr "Cambia canale" msgid "Switch background" msgstr "Cambia sfondo" msgid "Jump to..." msgstr "Vai a..." msgid "Background transparency" msgstr "Trasparenza sfondo" msgid "Show clock" msgstr "Mostra orologio" msgid "Auto-update pages" msgstr "Aggiorn. automatico pagine" msgid "OSD height" msgstr "Altezza OSD" msgid "OSD width" msgstr "Larghezza OSD" msgid "OSD horizontal align" msgstr "Allineamento orizzontale OSD" msgid "OSD vertical align" msgstr "Allineamento verticale OSD" msgid "Hide mainmenu entry" msgstr "Nascondi voce menu principale" msgid "Key bindings" msgstr "Tasti associati" msgid " Page number" msgstr " Numero pagina" osdteletext-0.9.4/po/de_DE.po0000644000175000017500000000315312117131615015332 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Klaus Schmidinger , 2000 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-05-04 15:33+0200\n" "Last-Translator: Klaus Schmidinger \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Sender (OK drücken): " msgid "Page" msgstr "Seite" msgid "not found" msgstr "nicht gefunden" msgid "Displays teletext on the OSD" msgstr "Zeigt den Videotext auf dem OSD an" msgid "Teletext" msgstr "Videotext" msgid "Zoom" msgstr "Vergrößern" msgid "Half page" msgstr "Halbe Seite" msgid "Change channel" msgstr "Kanal wechseln" msgid "Switch background" msgstr "Hintergrund ändern" msgid "Jump to..." msgstr "Springe zu..." msgid "Background transparency" msgstr "Hintergrund-Transparenz" msgid "Show clock" msgstr "Uhr anzeigen" msgid "Auto-update pages" msgstr "Seiten aktualisieren" msgid "OSD height" msgstr "OSD-Höhe" msgid "OSD width" msgstr "OSD-Breite" msgid "OSD horizontal align" msgstr "OSD horizontale Anordnung" msgid "OSD vertical align" msgstr "OSD vertikale Anordnung" msgid "Hide mainmenu entry" msgstr "Hauptmenüeintrag verstecken" msgid "Key bindings" msgstr "Tastenzuweisung" msgid " Page number" msgstr " Seitenzahl" osdteletext-0.9.4/po/pt_PT.po0000644000175000017500000000310312117131615015413 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Klaus Schmidinger , 2000 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2008-05-04 15:33+0200\n" "Last-Translator: Chris Silva \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Sender (Prima OK): " msgid "Page" msgstr "Página" msgid "not found" msgstr "Não encontrado" msgid "Displays teletext on the OSD" msgstr "Mostra o teletexto no OSD" msgid "Teletext" msgstr "Teletexto" msgid "Zoom" msgstr "Zoom" msgid "Half page" msgstr "Meia Página" msgid "Change channel" msgstr "Mudar canal" msgid "Switch background" msgstr "Mudar fundo" msgid "Jump to..." msgstr "Ir para" msgid "Background transparency" msgstr "Transparência do Fundo" msgid "Show clock" msgstr "Mostrar Relógio" msgid "Auto-update pages" msgstr "Auto actualizar páginas" msgid "OSD height" msgstr "Altura do OSD" msgid "OSD width" msgstr "Largura do OSD" msgid "OSD horizontal align" msgstr "Alinhamento Horizontal do OSD" msgid "OSD vertical align" msgstr "Alinhamento Vertical do OSD" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "Tecla alocada" msgid " Page number" msgstr " Número de Página" osdteletext-0.9.4/po/sk_SK.po0000644000175000017500000000316612117131615015410 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Klaus Schmidinger , 2000 # msgid "" msgstr "" "Project-Id-Version: osdteletext-0.9.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2011-02-15 21:11+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Kanál (stlačte OK): " msgid "Page" msgstr "Strana" msgid "not found" msgstr "nenájdená" msgid "Displays teletext on the OSD" msgstr "Zobrazí teletext na OSD" msgid "Teletext" msgstr "Teletext" msgid "Zoom" msgstr "Zväčšenie" msgid "Half page" msgstr "Polovica strany" msgid "Change channel" msgstr "Zmena kanálu" msgid "Switch background" msgstr "Prepnúť na pozadí" msgid "Jump to..." msgstr "Skoč na..." msgid "Background transparency" msgstr "Priesvitnosť pozadia" msgid "Show clock" msgstr "Zobraziť hodiny" msgid "Auto-update pages" msgstr "Aktualizácia stránok" msgid "OSD height" msgstr "OSD výška" msgid "OSD width" msgstr "OSD šírka" msgid "OSD horizontal align" msgstr "OSD vodorovné zarovnanie" msgid "OSD vertical align" msgstr "OSD zvyslé zarovnanie" msgid "Hide mainmenu entry" msgstr "Schovať položku v hlavnom menu" msgid "Key bindings" msgstr "Klávesové skratky" msgid " Page number" msgstr " Číslo strany" osdteletext-0.9.4/po/fr_FR.po0000644000175000017500000000331312117131615015366 0ustar tobiastobias# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Jean-Claude Repetto , 2001 # Olivier Jacques , 2003 # Gregoire Favre , 2003 # Nicolas Huillard , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-03-10 17:21+0100\n" "PO-Revision-Date: 2009-01-10 19:32+0100\n" "Last-Translator: Nival Michaël\n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Channel (press OK): " msgstr "Chaine (Appuyer sur OK): " msgid "Page" msgstr "Page" msgid "not found" msgstr "pas trouvé" msgid "Displays teletext on the OSD" msgstr "Affiche le télétexte sur l'OSD" msgid "Teletext" msgstr "Teletexte" msgid "Zoom" msgstr "Zoom" msgid "Half page" msgstr "Demi-Page" msgid "Change channel" msgstr "Changer la chaîne" msgid "Switch background" msgstr "Change le fond d'écran" msgid "Jump to..." msgstr "Aller à..." msgid "Background transparency" msgstr "Fond transparent" msgid "Show clock" msgstr "Afficher l'heure" msgid "Auto-update pages" msgstr "Mise à jour des pages" msgid "OSD height" msgstr "Hauteur OSD" msgid "OSD width" msgstr "Largeur OSD" msgid "OSD horizontal align" msgstr "Alignement horizontal de l'OSD" msgid "OSD vertical align" msgstr "Alignement vertical de l'OSD" msgid "Hide mainmenu entry" msgstr "" msgid "Key bindings" msgstr "Attribution des touches" msgid " Page number" msgstr " Nombre de pages" osdteletext-0.9.4/display.c0000644000175000017500000001574111737124466015250 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * display.c - Actual implementation of OSD display variants and * * Display:: namespace that encapsulates a single cDisplay. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * Changelog: * * 2005-03 initial version (c) Udo Richter * * * ***************************************************************************/ #include #include #include "setup.h" #include "display.h" #include "txtfont.h" // Static variables of Display:: namespace Display::Mode Display::mode=Display::Full; cDisplay *Display::display=NULL; void Display::SetMode(Display::Mode NewMode) { // (re-)set display mode. if (display!=NULL && NewMode==mode) return; // No change, nothing to do // OSD origin, centered on VDR OSD int x0=Setup.OSDLeft+(Setup.OSDWidth-ttSetup.OSDwidth)*ttSetup.OSDHAlign/100; int y0=Setup.OSDTop +(Setup.OSDHeight-ttSetup.OSDheight)*ttSetup.OSDVAlign/100; switch (NewMode) { case Display::Full: // Need to re-initialize *display: Delete(); // Try 4BPP display first: display=new cDisplay4BPP(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight); if (!display->Valid()) { // Failed, possibly out of memory delete display; // Try 2BPP display display=new cDisplay2BPP(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight); } break; case Display::HalfUpper: // Shortcut to switch from HalfUpper to HalfLower: if (mode==Display::HalfLower) { // keep instance. ((cDisplay4BPPHalf*)display)->SetUpper(true); break; } // Need to re-initialize *display: Delete(); display=new cDisplay4BPPHalf(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight,true); break; case Display::HalfLower: // Shortcut to switch from HalfUpper to HalfLower: if (mode==Display::HalfUpper) { // keep instance. ((cDisplay4BPPHalf*)display)->SetUpper(false); break; } // Need to re-initialize *display: Delete(); display=new cDisplay4BPPHalf(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight,false); break; } mode=NewMode; // If display is invalid, clean up immediately: if (!display->Valid()) Delete(); // Pass through OSD black transparency SetBackgroundColor((tColor)ttSetup.configuredClrBackground); } void Display::ShowUpperHalf() { // Enforce upper half of screen to be visible if (GetZoom()==cDisplay::Zoom_Lower) SetZoom(cDisplay::Zoom_Upper); if (mode==HalfLower) SetMode(HalfUpper); } cDisplay2BPP::cDisplay2BPP(int x0, int y0, int width, int height) : cDisplay(width,height) { // 2BPP display with color mapping osd = cOsdProvider::NewOsd(x0, y0); if (!osd) return; width=(width+3)&~3; // Width has to end on byte boundary, so round up tArea Areas[] = { { 0, 0, width - 1, height - 1, 2 } }; if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { DELETENULL(osd); return; } osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); InitPalette(); InitScaler(); CleanDisplay(); } tColor cDisplay2BPP::GetColorRGB(enumTeletextColor ttc, int Area) { switch (ttc) { case ttcBlack: return Background; case ttcRed: return clrRed; case ttcGreen: return clrYellow; case ttcYellow: return clrYellow; case ttcBlue: return Background; case ttcMagenta: return clrRed; case ttcCyan: return clrCyan; case ttcWhite: return clrCyan; case ttcTransparent: return Background; default: return Background; } } tColor cDisplay2BPP::GetColorRGBAlternate(enumTeletextColor ttc, int Area) { switch (ttc) { case ttcBlack: return clrCyan; case ttcRed: return clrYellow; case ttcGreen: return clrRed; case ttcYellow: return clrRed; case ttcBlue: return clrCyan; case ttcMagenta: return clrYellow; case ttcCyan: return Background; case ttcWhite: return Background; case ttcTransparent: return clrCyan; default: return Background; } } cDisplay4BPP::cDisplay4BPP(int x0, int y0, int width, int height) : cDisplay(width,height) { // 4BPP display for memory-modded DVB cards and other OSD providers osd = cOsdProvider::NewOsd(x0, y0); if (!osd) return; width=(width+1)&~1; // Width has to end on byte boundary, so round up tArea Areas[] = { { 0, 0, width - 1, height - 1, 4 } }; if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { DELETENULL(osd); return; } osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); InitPalette(); InitScaler(); CleanDisplay(); } cDisplay4BPPHalf::cDisplay4BPPHalf(int x0, int y0, int width, int height, bool upper) : cDisplay(width,height), Upper(upper), OsdX0(x0), OsdY0(y0) { osd=NULL; // Redirect all real init work to method InitOSD(); } void cDisplay4BPPHalf::InitOSD() { if (osd) delete osd; osd = cOsdProvider::NewOsd(OsdX0, OsdY0); if (!osd) return; int width=(Width+1)&~1; // Width has to end on byte boundary, so round up tArea Areas[] = { { 0, 0, width - 1, Height - 1, 4 } }; // Try full-size area first while (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { // Out of memory, so shrink if (Upper) { // Move up lower border Areas[0].y2=Areas[0].y2-1; } else { // Move down upper border Areas[0].y1=Areas[0].y1+1; } if (Areas[0].y1>Areas[0].y2) { // Area is empty, fail miserably DELETENULL(osd); return; } } // Add some backup // CanHandleAreas is not accurate enough if (Upper) { Areas[0].y2=Areas[0].y2-10; } else { Areas[0].y1=Areas[0].y1+10; } osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); InitPalette(); InitScaler(); CleanDisplay(); // In case we switched on the fly, do a full redraw Dirty=true; DirtyAll=true; Flush(); } osdteletext-0.9.4/menu.h0000644000175000017500000000453211737124466014550 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OSDTELETEXT_MENU__H #define OSDTELETEXT_MENU__H #include #include #include #include #include "txtrecv.h" #include "setup.h" extern int Stretch; class TeletextBrowser : public cOsdObject { public: TeletextBrowser(cTxtStatus *txtSt,Storage *s); ~TeletextBrowser(); void Show(void); static void ChannelSwitched(int ChannelNumber); virtual eOSState ProcessKey(eKeys Key); protected: enum Direction { DirectionForward, DirectionBackward }; void SetNumber(int i); void ShowPage(); void UpdateClock(); bool DecodePage(); void ChangePageRelative(Direction direction); void ChangeSubPageRelative(Direction direction); bool CheckPage(); void ShowAskForChannel(); bool CheckFirstSubPage(int startWith); void SetPreviousPage(int oldPage, int oldSubPage, int newPage); bool CheckIsValidChannel(int number); int PageCheckSum(); void ShowPageNumber(); void ExecuteAction(eTeletextAction e); int nextValidPageNumber(int start, Direction direction); char fileName[PATH_MAX]; char page[40][24]; int cursorPos; eTeletextAction TranslateKey(eKeys Key); bool pageFound; bool selectingChannel; bool needClearMessage; int selectingChannelNumber; int checkSum; cTxtStatus *txtStatus; bool suspendedReceiving; int previousPage; int previousSubPage; int pageBeforeNumberInput; time_t lastActivity; int inactivityTimeout; static int currentPage; static int currentSubPage; static tChannelID channel; static int currentChannelNumber; static TeletextBrowser* self; Storage *storage; private: void ChangeBackground(); }; #endif osdteletext-0.9.4/tables.h0000644000175000017500000001021611737124466015052 0ustar tobiastobias/* This file is copied from Ralph Metzler's vbidecode package. -*- c++ -*- */ /* tables.h - some data conversion tables for vbidecode */ #ifndef _TABLES_H #define _TABLES_H unsigned char invtab[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; unsigned char unhamtab[256] = { 0x01, 0xff, 0x81, 0x01, 0xff, 0x00, 0x01, 0xff, 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, 0xff, 0x00, 0x01, 0xff, 0x00, 0x80, 0xff, 0x00, 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff, 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07, 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x87, 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff, 0x86, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09, 0x02, 0x82, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff, 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x83, 0x03, 0x04, 0xff, 0xff, 0x05, 0x84, 0x04, 0x04, 0xff, 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, 0xff, 0x05, 0x05, 0x85, 0x04, 0xff, 0xff, 0x05, 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09, 0x0a, 0xff, 0xff, 0x0b, 0x8a, 0x0a, 0x0a, 0xff, 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff, 0xff, 0x0b, 0x0b, 0x8b, 0x0a, 0xff, 0xff, 0x0b, 0x0c, 0x8c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff, 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x8d, 0x0d, 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x89, 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, 0x88, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09, 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff, 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09, 0x0f, 0xff, 0x8f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff, 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x8e, 0xff, 0x0e, }; unsigned char cct2vtx_table[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0xef, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; #endif osdteletext-0.9.4/txtrecv.c0000644000175000017500000001646212117130631015263 0ustar tobiastobias/*************************************************************** -*- c++ -*- * Copyright (c) 2003,2004 by Marcel Wiesweg * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "txtrecv.h" #include "tables.h" #include "setup.h" #include "menu.h" #include #include #include #include #include #include #include #include #include #include cTelePage::cTelePage(PageID t_page, uchar t_flags, uchar t_lang,int t_mag, Storage *s) : mag(t_mag), flags(t_flags), lang(t_lang), page(t_page), storage(s) { memset(pagebuf,' ',26*40); } cTelePage::~cTelePage() { } void cTelePage::SetLine(int line, uchar *myptr) { memcpy(pagebuf+40*line,myptr,40); } void cTelePage::save() { unsigned char buf; StorageHandle fd; if ( (fd=storage->openForWriting(page)) ) { storage->write("VTXV4",5,fd); buf=0x01; storage->write(&buf,1,fd); buf=mag; storage->write(&buf,1,fd); buf=page.page; storage->write(&buf,1,fd); buf=flags; storage->write(&buf,1,fd); buf=lang; storage->write(&buf,1,fd); buf=0x00; storage->write(&buf,1,fd); buf=0x00; storage->write(&buf,1,fd); storage->write(pagebuf,24*40,fd); storage->close(fd); } } bool cTelePage::IsTopTextPage() { return (page.page & 0xFF) > 0x99 || (page.page & 0x0F) > 0x9; } cTxtStatus::cTxtStatus(bool storeTopText, Storage* storage) : receiver(NULL), storeTopText(storeTopText), storage(storage) { } cTxtStatus::~cTxtStatus() { delete receiver; } void cTxtStatus::ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView) { // Disconnect receiver if channel is 0, will reconnect to new // receiver after channel change. if (LiveView && ChannelNumber == 0) DELETENULL(receiver); // ignore if channel is 0 if (ChannelNumber == 0) return; // ignore if channel is invalid (highly unlikely, this will ever // be the case, but defensive coding rules!) cChannel* newLiveChannel = Channels.GetByNumber(ChannelNumber); if (newLiveChannel == NULL) return; // ignore non-live-channel-switching if (!LiveView || ChannelNumber != cDevice::CurrentChannel()) return; // live channel was changed // now re-attach the receiver to the new live channel DELETENULL(receiver); int TPid = newLiveChannel->Tpid(); if (TPid) { receiver = new cTxtReceiver(newLiveChannel, storeTopText, storage); cDevice::ActualDevice()->AttachReceiver(receiver); } TeletextBrowser::ChannelSwitched(ChannelNumber); } cTxtReceiver::cTxtReceiver(const cChannel* chan, bool storeTopText, Storage* storage) : cReceiver(chan, -1), cThread("osdteletext-receiver"), TxtPage(0), storeTopText(storeTopText), buffer((188+60)*75), storage(storage) { SetPids(NULL); AddPid(chan->Tpid()); storage->prepareDirectory(ChannelID()); // 10 ms timeout on getting TS frames buffer.SetTimeouts(0, 10); } cTxtReceiver::~cTxtReceiver() { Detach(); Activate(false); buffer.Clear(); delete TxtPage; } void cTxtReceiver::Stop() { Activate(false); } void cTxtReceiver::Activate(bool On) { if (On) { if (!Running()) { Start(); } } else if (Running()) { buffer.Signal(); Cancel(2); } } void cTxtReceiver::Receive(uchar *Data, int Length) { cFrame *frame=new cFrame(Data, Length); if (!buffer.Put(frame)) { // Buffer overrun delete frame; buffer.Signal(); } } void cTxtReceiver::Action() { while (Running()) { cFrame *frame=buffer.Get(); if (frame) { uchar *Datai=frame->Data(); for (int i=0; i < 4; i++) { if (Datai[4+i*46]==2 || Datai[4+i*46]==3) { for (int j=(8+i*46);j<(50+i*46);j++) Datai[j]=invtab[Datai[j]]; DecodeTXT(&Datai[i*46]); } } buffer.Drop(frame); } else buffer.Wait(); } buffer.Clear(); } uchar cTxtReceiver::unham16 (uchar *p) { unsigned short c1,c2; c1=unhamtab[p[0]]; c2=unhamtab[p[1]]; return (c1 & 0x0F) | (c2 & 0x0F) *16; } void cTxtReceiver::SaveAndDeleteTxtPage() { if (TxtPage) { if (storeTopText || !TxtPage->IsTopTextPage()) { TxtPage->save(); DELETENULL(TxtPage); } } } void cTxtReceiver::DecodeTXT(uchar* TXT_buf) { // Format of buffer: // 0x00-0x04 ? // 0x05-0x06 Clock Run-In? // 0x07 Framing Code? // 0x08 Magazine number (100-digit of page number) // 0x09 Line number // 0x0A..0x31 Line data // Line 0 only: // 0x0A 10-digit of page number // 0x0B 1-digit of page number // 0x0C Sub-Code bits 0..3 // 0x0D Sub-Code bits 4..6 + C4 flag // 0x0E Sub-Code bits 8..11 // 0x0F Sub-Code bits 12..13 + C5,C6 flag // 0x10 C7-C10 flags // 0x11 C11-C14 flags // // Flags: // C4 - Erase last page, new page transmitted // C5 - News flash, boxed display // C6 - Subtitle, boxed display // C7 - Suppress Header, dont show line 0 // C8 - Update, page has changed // C9 - Interrupt Sequence, page number is out of order // C10 - Inhibit Display // C11 - Magazine Serial mode // C12-C14 - Language selection, lower 3 bits int hdr,mag,mag8,line; uchar *ptr; uchar flags,lang; hdr = unham16 (&TXT_buf[0x8]); mag = hdr & 0x07; mag8 = mag ?: 8; line = (hdr>>3) & 0x1f; ptr = &TXT_buf[10]; switch (line) { case 0: { unsigned char b1, b2, b3, b4; int pgno, subno; b1 = unham16 (ptr); // Page no, 10- and 1-digit if (b1 == 0xff) break; SaveAndDeleteTxtPage(); b2 = unham16 (ptr+2); // Sub-code 0..6 + C4 b3 = unham16 (ptr+4); // Sub-code 8..13 + C5,C6 b4 = unham16 (ptr+6); // C7..C14 // flags: // 0x80 C4 - Erase page // 0x40 C5 - News flash // 0x20 C6 - Subtitle // 0x10 C7 - Suppress Header // 0x08 C8 - Update // 0x04 C9 - Interrupt Sequence // 0x02 C9 (Bug?) // 0x01 C11 - Magazine Serial mode flags=b2 & 0x80; flags|=(b3&0x40)|((b3>>2)&0x20); //?????? flags|=((b4<<4)&0x10)|((b4<<2)&0x08)|(b4&0x04)|((b4>>1)&0x02)|((b4>>4)&0x01); lang=((b4>>5) & 0x07); pgno = mag8 * 256 + b1; subno = (b2 + b3 * 256) & 0x3f7f; // Sub Page Number TxtPage = new cTelePage(PageID(ChannelID(), pgno, subno), flags, lang, mag, storage); TxtPage->SetLine((int)line,(uchar *)ptr); break; } case 1 ... 25: { if (TxtPage) TxtPage->SetLine((int)line,(uchar *)ptr); break; } /*case 23: { SaveAndDeleteTxtPage(); break; }*/ default: break; } } osdteletext-0.9.4/display.h0000644000175000017500000001120711737124466015246 0ustar tobiastobias/*************************************************************** -*- c++ -*- * * * display.h - Actual implementation of OSD display variants and * * Display:: namespace that encapsulates a single cDisplay. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * Changelog: * * 2005-03 initial version (c) Udo Richter * * * ***************************************************************************/ #ifndef OSDTELETEXT_DISPLAY_H_ #define OSDTELETEXT_DISPLAY_H_ #include "displaybase.h" #include namespace Display { // The Display:: namespace mainly encapsulates a cDisplay *display variable // and allows NULL-safe access to display members. // Additionally, selects via mode the actually used instance for *display. enum Mode { Full, HalfUpper, HalfLower }; // Full mode: 2BPP or 4BPP full screen display, depending on memory constrains // HalfUpper: 4BPP display of upper half, drop lower half if out of memory // HalfLower: 4BPP display of lower half, drop upper half if out of memory extern Mode mode; extern cDisplay *display; // Access to display mode: void SetMode(Display::Mode mode); inline void Delete() { if (display) { DELETENULL(display); } } void ShowUpperHalf(); // Make sure the upper half of screen is visible // eg. for entering numbers etc. // Wrapper calls for various *display members: inline bool GetBlink() { if (display) return display->GetBlink(); else return false; } inline bool SetBlink(bool blink) { if (display) display->SetBlink(blink); else return false; } inline bool GetConceal() { if (display) return display->GetConceal(); else return false; } inline bool SetConceal(bool conceal) { if (display) display->SetConceal(conceal); else return false; } inline cDisplay::enumZoom GetZoom() { if (display) return display->GetZoom(); else return cDisplay::Zoom_Off; } inline void SetZoom(cDisplay::enumZoom zoom) { if (display) display->SetZoom(zoom); } inline void SetBackgroundColor(tColor c) { if (display) display->SetBackgroundColor(c); } inline tColor GetBackgroundColor() { if (display) return display->GetBackgroundColor(); else return 0; } inline void HoldFlush() { if (display) display->HoldFlush(); } inline void ReleaseFlush() { if (display) display->ReleaseFlush(); } inline void RenderTeletextCode(unsigned char *PageCode) { if (display) display->RenderTeletextCode(PageCode); } inline void DrawClock() { if (display) display->DrawClock(); } inline void DrawPageId(const char *text) { if (display) display->DrawPageId(text); } inline void DrawMessage(const char *txt) { if (display) display->DrawMessage(txt); } inline void ClearMessage() { if (display) display->ClearMessage(); } } class cDisplay2BPP : public cDisplay { // 2BPP (4 color) OSD display // Use static color mapping to limit color depth public: cDisplay2BPP(int x0, int y0, int width, int height); virtual tColor GetColorRGB(enumTeletextColor ttc, int Area); virtual tColor GetColorRGBAlternate(enumTeletextColor ttc, int Area); }; class cDisplay4BPP : public cDisplay { // 4BPP (16 color) OSD display // No need for color mapping public: cDisplay4BPP(int x0, int y0, int width, int height); }; class cDisplay4BPPHalf : public cDisplay { // 4BPP (16 color) OSD display with auto size reduction on memory constrains // Automatically tries to make visible area as big as possible // No need for color mapping bool Upper; // Prefer to show upper half or lower half? int OsdX0,OsdY0; // Needed to re-initialize osd public: cDisplay4BPPHalf(int x0, int y0, int width, int height, bool upper); bool GetUpper() { return Upper; } void SetUpper(bool upper) { if (Upper!=upper) { Upper=upper; InitOSD(); } } protected: void InitOSD(); }; #endif