[MPlayer-cvslog] r23530 - in trunk: Changelog DOCS/man/en/mplayer.1 DOCS/tech/MAINTAINERS DOCS/tech/slave.txt cfg-common.h command.c configure input/input.c input/input.h libvo/sub.c libvo/sub.h mpcommon.c mplayer.c spudec.c spudec.h stream/Makef

Michael Niedermayer michaelni at gmx.at
Mon Jun 11 10:00:48 CEST 2007


Hi

On Mon, Jun 11, 2007 at 10:31:19AM +0700, Vladimir Voroshilov wrote:
> 2007/6/11, Michael Niedermayer <michaelni at gmx.at>:
> > Hi
> >
> > On Sun, Jun 10, 2007 at 10:17:50PM +0200, Diego Biurrun wrote:
> > > On Sun, Jun 10, 2007 at 11:04:49AM +0200, Nico Sabbi wrote:
> > > > voroshil wrote:
> > > >
> > > > >Log:
> > > > >Teletext support for tv:// (v4l and v4l2 only)
> > > > >
> > > > >modified patch from Otvos Attila oattila at chello dot hu
> > > > >
> > > > >Added:
> > > > >   trunk/stream/tvi_vbi.c   (contents, props changed)
> > > > >   trunk/stream/tvi_vbi.h   (contents, props changed)
> > > > >Modified:
> > > > >   trunk/Changelog
> > > > >   trunk/DOCS/tech/MAINTAINERS
> > > > >   trunk/DOCS/tech/slave.txt
> > > > >   trunk/cfg-common.h
> > > > >   trunk/command.c
> > > > >   trunk/configure
> > > > >   trunk/input/input.c
> > > > >   trunk/input/input.h
> > > > >   trunk/libvo/sub.c
> > > > >   trunk/libvo/sub.h
> > > > >   trunk/mpcommon.c
> > > > >   trunk/mplayer.c
> > > > >   trunk/spudec.c
> > > > >   trunk/spudec.h
> > > > >   trunk/stream/Makefile
> > > > >   trunk/stream/tv.c
> > > > >   trunk/stream/tv.h
> > > >
> > > > couldn't you split it in self-contained pieces?
> > >
> > > This commit breaks a big number of policy rules.  Vladimir, why did you
> > >
> > > - give no warning that you would commit the patch,
> > > - commit to other people's code without approval,
> > > - not split the patch into self-contained small pieces,
> > > - ...?
> > >
> > > Additionally the patch litters MPlayer with a huge number of #ifdefs,
> > > indentation mixes tabs and spaces inconsistently, documentation is full
> > > of typos and partially buggy, the new files don't come with license
> > > headers.
> > >
> > > If I had had a chance to review and comment on this beforehand I would
> > > have requested nearly every build system and documentation line to be
> > > changed.  I'm also confident there has to be a way to implement this
> > > more cleanly.
> >
> > ive not really looked at the patch/commit but 77k for teletext decoding
> > with some external lib .... hmm
> > ive written a teletext decoder in 1999 and that was <22k including
> > demodulation, error correcting, color, caching of pages and subpages
> Main code is about 30k (without comments). 10k - rendering, other 30k
> is properties/slave commands implementation/configure/interface with
> mplayer internals.
> 
> Is it to possible integrate your implementation 

my code is not related to mplayer and is a huge mess. ive just written
it for fun in 98 or 99 or so. writing clean or portable code was not my
goal when i wrote it, just getting it well working was enough ...

either way ive attached the relevant files, feel free to use anything from
it under LGPL or GPL if you like but i doubt theres much directly useable


> (i'll prefer solution
> without external lib)?

me too but i dont know if its possible with v4l*, can it portably capture
the lines which contain teletext?

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The worst form of inequality is to try to make unequal things equal.
-- Aristotle
-------------- next part --------------
//2010 0.1 Copyright (C) Michael Niedermayer 1998

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include "2_all.h"
#include "2010.h"
#include "2_crypt.h"
#include "2_gfunc.h"
#include "2_txt.h"
#include "2_71x6.h"

#define FORCE_ORDER false

extern int vgax, vgay, wndx, wndy, mc, x_field;
extern bool iState, helpState;
extern volatile int scales_x, scalee_x;
extern volatile int scales_y, scalee_y;
extern VID2MEMBUF *actVid2MemBufp;
extern int some;
extern int yuvMode;
extern int infoPosX, infoPosY;
extern int grabf;

#define FREQ_TXT 6.9375E6
#define FIXP_SH 16
#define ONE_FIXP (1<<FIXP_SH)
#define BYTES 42

char reqChanStr[16];
int reqChanNum=0;
int reqPage=0x100;
int reqSubPage=0;
char findTxt[128]={0,0,};

       // FIX all langs and add graph to ascii if saved in text

static int reMapTab[8][13]={
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x23, 0x24, 0x15, 0x8E, 0x99, 0x9A, 0x5E, 0x5F, 0xA7, 0x84, 0x94, 0x81, 0xE1},

  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6},
  {0x9C, 0x24, 0x40, 0x1B, 0xAB, 0x1A, 0x18, 0x23, 0xC4, 0xAC, 0xBA, 0x00, 0xF6}
 };

static int isReMap[128]={
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8,
 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,11,12,13, 0 };

static inline void txtCpy(char *to, u_char *from, int num){
  for(int i=0; i<num; i++){
    if((from[i]&0x80) && !(to[i]&0x80)) continue;
    to[i]=from[i];
  }
}

static inline float atan3(const float f1, const float f2){
  float out;
                     // ?! atan2 crashes 
  asm(//"int $3\n\t"
      "fpatan \n\t"
      : "=t"(out)
      : "0"(f2), "u"(f1)
      : "st(1)"
                          );

  return out;
}

static inline void reMapCpy(char *to, char *from, int num, int land){
  for(int i=0; i<num; i++){
    char a= from[i] & 0x7F;
    if(a<0x20) a=0x20;
    if(isReMap[a]) to[i]=reMapTab[land][ isReMap[a] - 1 ];
    else           to[i]=a;
  }
}

static signed char corrHamm48[256]={
  0x01, 0xff, 0x01, 0x01, 0xff, 0x00, 0x01, 0xff,  0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, 
  0xff, 0x00, 0x01, 0xff, 0x00, 0x00, 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, 0x07, 
  0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff,  0x06, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, 
  0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09,  0x02, 0x02, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, 
  0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff,  0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03, 
  0x04, 0xff, 0xff, 0x05, 0x04, 0x04, 0x04, 0xff,  0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, 
  0xff, 0x05, 0x05, 0x05, 0x04, 0xff, 0xff, 0x05,  0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, 
  0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09,  0x0a, 0xff, 0xff, 0x0b, 0x0a, 0x0a, 0x0a, 0xff, 
  0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff,  0xff, 0x0b, 0x0b, 0x0b, 0x0a, 0xff, 0xff, 0x0b, 
  0x0c, 0x0c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff,  0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, 
  0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x0d, 0x0d,  0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, 
  0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x09,  0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, 
  0x08, 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, 0x0f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, 
  0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff,  0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x0e, 0xff, 0x0e };

static signed char fixParity[256];

static inline int sample(byte *b, int fixpPos){
  const int ndx  = fixpPos>>FIXP_SH;
  const int frac = fixpPos & (ONE_FIXP-1);

  const int a1= int(b[ ndx<<1     ]) * (ONE_FIXP - frac); 
  const int a2= int(b[(ndx<<1) + 2]) * (           frac);

  return (a1+a2) >> FIXP_SH;
}

void txt_decrypt(void){
  char textbuf[9][128];

  int cross= (some-20)*1000;

  static int hammErr=0;
  static int pages=0;
  static double parities= 0;
  static double magics= 0;

  const double freqPix2= double(wndx) / double(x_field) * FREQ_PIX;
  const int delta= int(freqPix2/FREQ_TXT*ONE_FIXP);
  const double angDelta= FREQ_TXT/freqPix2*PI;

//  byte rawMagic[16]={255,   0, 255,   0, 255,   0, 255,   0,
//                     255, 255, 255,   0,   0, 255,   0,   0 };
  int clocks= clock();

  static CACHE1 *cache1=new CACHE1[1024];
  static int cache1Size=0;
  static bool first=true;
  static color txtColor[8];
  static MAG mag[8];
  static GETTAB *getTab=new GETTAB[1024];
  static int getTabNum=0;
  if(first){
    FILE *f= fopen("chaninf.txt", "rb");
    if(f==NULL) error(TxtFile);
    while(!feof(f)){
      int s=fscanf(f, "%27[^\n\r]%*[\n\r]", cache1[cache1Size].chan);
      if(s==0) break;
//      printf("%s\n", cache1[cache1Size].chan);
      cache1[cache1Size].pt= NULL;
      cache1Size++;
    }
    fclose(f);

    f= fopen("get.txt", "rb");
    if(f!=NULL){
      while(!feof(f)){
        int s=fscanf(f, "%X %d %14[^\n\r]%*[\n\r]", &getTab[getTabNum].page,
                                                    &getTab[getTabNum].clockDelta,
                                                     getTab[getTabNum].name);
        if(s==0) break;

        getTab[getTabNum].nextClock=0;
        getTab[getTabNum].clockDelta*=60*CLOCKS_PER_SEC;;

        for(int i=0; getTab[getTabNum].name[i]!=0; i++)
          if(getTab[getTabNum].name[i]=='.') getTab[getTabNum].name[i]=' ';

        char name[127];
        sprintf(name, "%s.txt", getTab[getTabNum].name);
        getTab[getTabNum].f= fopen(name, "ab");
        if(getTab[getTabNum].f==NULL) error(error_code(-999));
        if(ftell(getTab[getTabNum].f)==0)
          fprintf(getTab[getTabNum].f, "5 1 1 %s\n", getTab[getTabNum].name);

//        printf("%X %d  %d %s\n", getTab[getTabNum].page, getTab[getTabNum].nextClock,  getTab[getTabNum].clockDelta,
//        getTab[getTabNum].name);
        getTabNum++;
      }
    }
    fclose(f);

    for(int i=0; i<256; i++){
      int j=i&0x7F;                 
      j^= j+j;                      
      j^= j<<2;                     
      j^= j<<4;                     
      fixParity[i]= i ^ (j&0x80) ^ 0x80;  
    }
    txtColor[0].init(  0,  0,  0, true);
    txtColor[1].init(255,  0,  0, true);
    txtColor[2].init(  0,255,  0, true);
    txtColor[3].init(255,255,  0, true);
    txtColor[4].init(  0,  0,255, true);
    txtColor[5].init(255,  0,255, true);
    txtColor[6].init(  0,255,255, true);
    txtColor[7].init(255,255,255, true);

    for(int i=0; i<8; i++) mag[i].pt=NULL;
    first=false;
  }

  byte data[64];

  int txtHack=4;
  static int txtHackState=0;

  int linep=-(vgax<<4);
  for(int line=0; line<40; line++){
    linep+=vgax<<4;
    if(line==20) linep=vgax<<3;

    if(txtHackState) break;


    int avg=0;
    for(int x=0; x<((10*delta)>>FIXP_SH); x++){
      avg+=actVid2MemBufp->b[linep + (x<<1) + 1];
    }
    avg/=((10*delta)>>FIXP_SH);

        // FIX ? optimize in fixp and lut ...
    double si=0, co=0;
    double ang=0;
    for(int x=0; x<12; x++){
      const int amp= actVid2MemBufp->b[linep + (x<<1) + 1];
      si+= sin(ang)*(amp-avg);
      co+= cos(ang)*(amp-avg);
      ang+= angDelta;
//      actVid2MemBufp->b[linep + (x<<1) + 1]= 255;
    }
    int xFixp= int(atan3(si,co)/PI*freqPix2/FREQ_TXT*ONE_FIXP);


    const int magic= 0xAAE4;

    int r=0;
    int x=xFixp>>FIXP_SH;
    while(x < 70){
      r=(r<<1) & 0xFFFF;

      int score= sample( &actVid2MemBufp->b[linep + 1], xFixp );

      if(score > avg) r|=1;
//      actVid2MemBufp->b[linep + (x<<1) + 1]= (r&1)*255;
      xFixp+=delta;
      x=xFixp>>FIXP_SH;
      if(r==magic) break;
    }

    if(x>=70) continue;
    magics++;
   
/*  
    actVid2MemBufp->b[linep + (x<<1)    ]= 128;
    actVid2MemBufp->b[linep + (x<<1) + 1]= 255;
    actVid2MemBufp->b[linep + (x<<1) + 2]= 0  ;
    actVid2MemBufp->b[linep + (x<<1) + 3]= 255;
    
    continue;
*/
    r=0;

    for(int decoded=1; decoded<=(BYTES<<3); decoded++){
      r>>=1;

      int score= sample( &actVid2MemBufp->b[linep + 1], xFixp );

      if(score > avg) r|=0x80;
//      actVid2MemBufp->b[linep + (x<<1) + 1]= (r&0x80)/0x80*255;

      if(!(decoded & 0x07)){
        data[(decoded>>3) - 1]=r;
        r=0;
      }

      xFixp+=delta;
      x=xFixp>>FIXP_SH;
    }

    const int d0= corrHamm48[ data[0] ];
    const int d1= corrHamm48[ data[1] ];

    if(d0<0 || d1<0){ hammErr++; continue;}

    if(line==0 || line==39) txtHack+=1000;
    else txtHack--;

    const int magAddr= d0 & 0x7;
    const int rowAddr= (d0>>3) | (d1<<1);       

//    printf("lrm %d %d %d\n", line, rowAddr, magAddr);

    if(rowAddr==0){
      mag[magAddr].pt=NULL;
      const int d2= corrHamm48[ data[2] ];
      const int d3= corrHamm48[ data[3] ];
      const int d4= corrHamm48[ data[4] ];
      const int d5= corrHamm48[ data[5] ];
      const int d6= corrHamm48[ data[6] ];
      const int d7= corrHamm48[ data[7] ];
      const int d8= corrHamm48[ data[8] ];
      const int d9= corrHamm48[ data[9] ];

      if(d2<0 || d3<0 || d4<0 || d5<0 || d6<0 || d7<0 || d8<0 || d9<0){
        hammErr++;
        continue;
      }

      const int lsPage = d2 | (d3<<4);
      const int subPage=(d4 | (d5<<4) | (d6<<8) | (d7<<12)) & 0x3F7F;
      const int page   =(magAddr<<8) | lsPage;
      mag[magAddr].land= d9 & 0x7;

      for(int i=10; i<BYTES; i++){
        data[i]= fixParity[ data[i] ];
      }

      int bestLen=0;
      int best=0;
      int cache1Ndx;       
      for(cache1Ndx=0; cache1Ndx<cache1Size; cache1Ndx++){
        for(int tryp=10; tryp<BYTES-8; tryp++){
          for(int pos=0;; pos++){
            if(pos+tryp>=BYTES-8) break;
            if(cache1[cache1Ndx].chan[pos] == 0) {
              if(pos>bestLen){
                bestLen=pos;
                best=cache1Ndx;
              }
              break;
            }
            if(   toupper(cache1[cache1Ndx].chan[pos]) != toupper(data[tryp+pos])
               && cache1[cache1Ndx].chan[pos] != 0x20) break;
          }
        }
      }

      if(bestLen==0){
        printf(" ERR Unknown Stuff: %32s\n", &data[10]);
        mag[magAddr].pt=NULL;
        continue;
      }
      cache1Ndx=best;
             
      if(cache1[cache1Ndx].pt==NULL){
        cache1[cache1Ndx].pt= new CACHE2*[0x800];
        for(int i=0; i<0x800; i++) cache1[cache1Ndx].pt[i]=NULL;
      }

      if(cache1[cache1Ndx].pt[page]==NULL){
        pages++;
        cache1[cache1Ndx].pt[page]= new CACHE2;
        cache1[cache1Ndx].pt[page]->next=NULL;
        cache1[cache1Ndx].pt[page]->seen=false;
        cache1[cache1Ndx].pt[page]->land=mag[magAddr].land;
        memset(cache1[cache1Ndx].pt[page]->text, 0xFF, 40*LINES);
        mag[magAddr].pt= cache1[cache1Ndx].pt[page];
        mag[magAddr].order=0;
      }
      else{
        CACHE2 *p=cache1[cache1Ndx].pt[page];
        while(p->next!=NULL && p->next->sub<=subPage) p=p->next;

        if(p->sub==subPage) mag[magAddr].pt= p, mag[magAddr].order=0;        
        else{
          pages++;
          CACHE2 *temp= new CACHE2;
          memset(temp->text, 0xFF, 40*LINES);

          if(p->sub<subPage){
            temp->next= p->next;
            p->next= temp;
          }
          else{
            temp->next= cache1[cache1Ndx].pt[page];
            cache1[cache1Ndx].pt[page]= temp;
          }

          temp->seen=false;
          mag[magAddr].pt= temp;
          mag[magAddr].order=0;
        }
      }

      mag[magAddr].pt->land=mag[magAddr].land;
      mag[magAddr].pt->sub=subPage;
      mag[magAddr].pt->page=page;
      mag[magAddr].order=0;
      txtCpy(&mag[magAddr].pt->text[rowAddr*40], data+10, 32);

    }
    else if(rowAddr<LINES){
      if(FORCE_ORDER && mag[magAddr].order>=rowAddr) mag[magAddr].pt=NULL;
      if(mag[magAddr].pt==NULL) continue;
      mag[magAddr].order=rowAddr;

      for(int i=2; i<BYTES; i++){
        data[i]= fixParity[ data[i] ];
        if(data[i]&0x80) parities++;
      }
      txtCpy(&mag[magAddr].pt->text[rowAddr*40], data+2, 40);

      char temp[40];
      reMapCpy(temp, &mag[magAddr].pt->text[rowAddr*40], 40, mag[magAddr].pt->land);
      for(int i=0; i<40; i++){
        if(temp[i]==',') temp[i]='.';
      }

      for(int getTabNdx=0; getTabNdx<getTabNum; getTabNdx++){
        if(mag[magAddr].pt->page!=getTab[getTabNdx].page) continue;

        if(clocks<getTab[getTabNdx].nextClock) continue;

        int len=strlen(getTab[getTabNdx].name);
        int p;
        for(p=0; p<40-len; p++){
          if(!strncasecmp(&temp[p], getTab[getTabNdx].name, len)) break;
        }
        if(p==40) continue;

        float val=-1;
        int skip=0;
        for(p+=len; p<40; p++){
          const char c= temp[p];

          if(c=='+' || c=='-') skip++;
          else if(c>='0' && c<='9'){
            if(skip>0) skip=-skip;
            if(skip==0){
              sscanf(&temp[p], "%f", &val);
              break;
            }
          }
          else if(c!='.'){
            if(skip<0) skip=-skip-1;
          }
        }
        if(val==-1 || val==0.0) continue;


        for(;p<40; p++) if(temp[p]==':') break;
        int h=-1, m=-1;
        if(p<40){
          sscanf(&temp[p - 2], "%d:%d", &h, &m);
        }


        printf("%s, %f\n", getTab[getTabNdx].name, val );

        time_t t;
        time(&t);
        tm *tim= gmtime(&t);
        if(h!=-1) tim->tm_hour=h;
        if(m!=-1) tim->tm_min=m;

        fprintf(getTab[getTabNdx].f, "%04d %02d %02d  %02d %02d    %f\n",
          tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday, tim->tm_hour, tim->tm_min ,val);

        getTab[getTabNdx].nextClock= clocks + getTab[getTabNdx].clockDelta;

        break;
      }
    }
  }

  memset(actVid2MemBufp->b, 0, vgax*vgay<<mc);
/*
  if(yuvMode<2) memset(actVid2MemBufp->b, 0, vgax*vgay<<mc);
  yuvMode++;
  if(yuvMode>2) yuvMode=2;
  */

  if(txtHack>0 && txtHackState==0) txtHackState=14;

  if(txtHackState>0){
    doTxtHack(txtHackState);
    txtHackState--;
  }

  if(iState || helpState) return;

//  return;

  static int lastReqPage=-1, lastReqSubPage=-1, lastReqChanNum=-1;

    // FIX reqChanStr
    // FIX add noAutoSeek

  const int seekChanDelta=    (reqChanNum < lastReqChanNum) ? -1 : 1;
  const int seekPageDelta=    (reqPage    < lastReqPage   ) ? -1 : 1;
  const int seekSubPageDelta= (reqSubPage < lastReqSubPage) ? -1 : 1;

  reqPage&=0x7FF;
  if(reqSubPage<0) reqSubPage=0;
  if(reqChanNum<0          ) reqChanNum= cache1Size-1;
  if(reqChanNum>=cache1Size) reqChanNum= 0;

  int start=reqChanNum;
  do{
    if(cache1[reqChanNum].pt!=NULL) break;
    reqChanNum+= seekChanDelta;
    if(reqChanNum<0          ) reqChanNum= cache1Size-1;
    if(reqChanNum>=cache1Size) reqChanNum= 0;
  }while(start!=reqChanNum);

  if(cache1[reqChanNum].pt==NULL) return;

  CACHE2 *p=NULL;
  bool reqSearch=true;
  if((findTxt[0]) && (findTxt[1])){
    findTxt[0]=0;

    bool found=false;
    int start=reqPage;
    int page=start+1;
    const int len=strlen(&findTxt[1]);
    while(page!=start){
      p=cache1[reqChanNum].pt[page];
      while(p!=NULL){
        for(int i=0; i<LINES*40-len; i++)
          if(!strncasecmp(&findTxt[1], &p->text[i], len)){
            found=true;
            break;
          }
        if(found) break;
        p=p->next;
      }
      if(found) break;
      page++;
      page&=0x7FF;
    }
    if(found){
      reqPage=page;
      reqSubPage=p->sub;
      reqSearch=false;
    }
  }
  if(reqSearch){

    start=reqPage;
    do{
      if(cache1[reqChanNum].pt[reqPage]!=NULL) break;
      reqPage+= seekPageDelta;
      reqPage&= 0x7FF;
    }while(start!=reqPage);

    if(cache1[reqChanNum].pt[reqPage]==NULL) return;

    p=cache1[reqChanNum].pt[reqPage];
    CACHE2 *firstp=p, *lastp=p, *largep=NULL, *smallp=NULL;

    while(p!=NULL){
      if(p->sub==reqSubPage) break;
      if(p->sub<reqSubPage && (smallp==NULL || p->sub>smallp->sub)) smallp=p;
      if(p->sub>reqSubPage && (largep==NULL || p->sub<largep->sub)) largep=p;
      lastp=p;
      p=p->next;
    }

    if(p==NULL){
      if(largep==NULL) largep=firstp;
      if(smallp==NULL) smallp=lastp;
      if(seekSubPageDelta>0) p=largep;
      else                   p=smallp;
    }

    reqSubPage=p->sub;
  }

  int yPos=0;
  for(int line=0; line<LINES; line++){
    int fgColorNdx=7;
    int bgColorNdx=0;
    bool flash=false;
    bool graph=false;
    bool contGraph=true;
    int xs=0;
    int xPos=10;

    while(xs<40){
      while(xs<40 && (     p->text[line*40 + xs] < 0x20
                      || ((p->text[line*40 + xs]&0x20) && graph) ) ){
        const int d= p->text[line*40 + xs];
        if(d<0x20){
          if((d&0xF)<8){
            fgColorNdx= d&0xF;
            if(d&0x10) graph=true;
            else       graph=false;
          }
          else if(d==0x1C) bgColorNdx=0;
          else if(d==0x1D) bgColorNdx=fgColorNdx;
          else if(d==0x19) contGraph=true;
          else if(d==0x1A) contGraph=false;
          rect(xPos, yPos+1, xPos+9, yPos+13, txtColor[bgColorNdx].col);
        }
        else{
          rect(xPos, yPos+1, xPos+9, yPos+13, txtColor[bgColorNdx].col);
          if(contGraph){
            if(d&0x01) rect(xPos  , yPos+1, xPos+4, yPos+4 , txtColor[fgColorNdx].col);
            if(d&0x02) rect(xPos+4, yPos+1, xPos+9, yPos+4 , txtColor[fgColorNdx].col);
            if(d&0x04) rect(xPos  , yPos+4, xPos+4, yPos+8 , txtColor[fgColorNdx].col);
            if(d&0x08) rect(xPos+4, yPos+4, xPos+9, yPos+8 , txtColor[fgColorNdx].col);
            if(d&0x10) rect(xPos  , yPos+8, xPos+4, yPos+13, txtColor[fgColorNdx].col);
            if(d&0x40) rect(xPos+4, yPos+8, xPos+9, yPos+13, txtColor[fgColorNdx].col);
          }
          else{
            if(d&0x01) rect(xPos+1, yPos+2, xPos+4, yPos+4 , txtColor[fgColorNdx].col);
            if(d&0x02) rect(xPos+5, yPos+2, xPos+9, yPos+4 , txtColor[fgColorNdx].col);
            if(d&0x04) rect(xPos+1, yPos+5, xPos+4, yPos+8 , txtColor[fgColorNdx].col);
            if(d&0x08) rect(xPos+5, yPos+5, xPos+9, yPos+8 , txtColor[fgColorNdx].col);
            if(d&0x10) rect(xPos+1, yPos+9, xPos+4, yPos+13, txtColor[fgColorNdx].col);
            if(d&0x40) rect(xPos+5, yPos+9, xPos+9, yPos+13, txtColor[fgColorNdx].col);
          } 
        }   

        xPos+=9;
        xs++;
      }

      int xe=xs;
      if(xs>=40) break;

      while(xe<40 && p->text[line*40 + xe] >= 0x20
                  && (!(p->text[line*40 + xe]&0x20) || !graph)  ) xe++;
      reMapCpy(textbuf[0], &p->text[line*40 + xs], xe-xs, p->land);


      textbuf[0][xe-xs]=0;
      rect(xPos, yPos+1, xPos+9*(xe-xs), yPos+13, txtColor[bgColorNdx].col);
      gprint(xPos, yPos, txtColor[fgColorNdx].col, textbuf[0]);

      xPos+=(xe-xs)*9;

      xs=xe;
    }

    if(line==0){
      sprintf(textbuf[0], " %d %f", pages, parities);
      gprint(10+32*9, yPos, txtColor[7].col, textbuf[0]);
    }

    yPos+=12;
  }

  if(grabf){
    char name[13]="12345678.123";
    if(grabf==1)
      sprintf(name, "%3X%3X.TXT", reqChanNum, reqPage);
    else
      sprintf(name, "%3X.TXT", reqChanNum);

    FILE *f= fopen(name, "wb");
    if(f==NULL) error(TxtFile);

    char temp[LINES*40+1];

    if(grabf==1){
      CACHE2 *p=cache1[reqChanNum].pt[reqPage];
      while(p!=NULL){
        reMapCpy(temp, p->text, 40*LINES, p->land);
        for(int y=0; y<LINES; y++){
          for(int x=0; x<40; x++){
            char a= temp[x + y*40];
            fputc(a, f);
          }
          fputs("\n", f);
        }
        p=p->next;
        fputs("\n", f);
      }
    }
    else{
      for(int page=0; page<0x800; page++){
        CACHE2 *p=cache1[reqChanNum].pt[page];
        while(p!=NULL){
          reMapCpy(temp, p->text, 40*LINES, p->land);
          for(int y=0; y<LINES; y++){
            for(int x=0; x<40; x++){
              char a= temp[x + y*40];
              fputc(a, f);
            }
            fputs("\n", f);
          }
          p=p->next;
          fputs("\n", f);
        }
      }
    }

    grabf=0;
  }



  lastReqPage=   reqPage;
  lastReqSubPage=reqSubPage;
  lastReqChanNum=reqChanNum;

  infoPosY+=5;

  parities*= 0.9;
  magics*=0.9;
}
      


-------------- next part --------------
//2010 0.1 Copyright (C) Michael Niedermayer 1998
#ifndef n2_txt_h
#define n2_txt_h

#define LINES 25

struct CACHE2{
  int page;
  int sub;
  bool seen;
  char text[LINES*40];
  CACHE2 *next;
  int land;
};

struct CACHE1{
  char chan[28];
  CACHE2 **pt;
};

struct MAG{
  CACHE2 *pt;
  int order;
  int land;
};

struct GETTAB{
  int page;
  char name[15];
  FILE *f;
  int clockDelta;
  int nextClock;
};


void txt_decrypt(void);

#endif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-cvslog/attachments/20070611/906a854c/attachment.pgp>


More information about the MPlayer-cvslog mailing list