Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Multiple languaghes



Erm..the patch is now attached... *grin*

BB

Ben Buxton <bb@cactii.net> uttered the following thing:
> nilsn <nilsn@nilux.com> uttered the following thing:
> > I have a made a patch that works for me, well almost perfectly, it sometimes
> > happens that it selects the wrong audiochannel, but a simple channel switch
> > back and forth fixes that:).
> > 
> > Feel free to fix this problem, and any other you happend to find, just
> > notice me
> > about the fixes:)
> > 
> > Just remember to "make clean" before compiling, dunno why but some people
> > have had problems with this:)
> > And please dont use both patches since they are just 2 diffrent way's of
> > doing
> > the same thing, and will surely not work well togheter:)
> 
> I found a bug in this patch, which caused VDR to crash whenever a
> channel was selected that had multiple Apids, but none of them in the
> preferred language. It seems that the PrefferedApid variable was not
> being initialised in this case.
> 
> I fixed it by adding:
> 
> PrefferedApid=&apids[0];
> 
> To the top of the cChannel::SetPrefferedAlang() function in channels.s 
> and removing the 'else' chunk, so that this variable always gets 
> initialised with something.
> 
> Attached is the revised patch, with a new version number. I've also been
> pedantic and corrected the spelling of 'preferred' throughout. :)
> 
> Ben
> 
> 
diff -ruN vdr-1.3.12/channels.c vdr-1.3.12-preffered/channels.c
--- vdr-1.3.12/channels.c	2004-04-03 15:42:06.000000000 +0200
+++ vdr-1.3.12-preffered/channels.c	2004-08-11 01:13:24.000000000 +0200
@@ -178,6 +178,7 @@
   modification = CHANNELMOD_NONE;
   linkChannels = NULL;
   refChannel   = NULL;
+  audiochannel = 0;
 }
 
 cChannel::cChannel(const cChannel &Channel)
@@ -195,6 +196,7 @@
   sid          = 0;
   rid          = 0;
   number       = 0;
+  audiochannel = 0;
   groupSep     = false;
   modification = CHANNELMOD_NONE;
   linkChannels = NULL;
@@ -406,6 +408,7 @@
          dpids[i] = Dpids[i];
          strn0cpy(dlangs[i], DLangs[i], 4);
          }
+     SetPreferredAlang(MAXAPIDS);
      tpid = Tpid;
      modification |= CHANNELMOD_PIDS;
      Channels.SetModified();
@@ -675,6 +678,7 @@
                  p = NULL;
                  }
            apids[NumApids] = 0;
+           SetPreferredAlang(NumApids);
            if (dpidbuf) {
               char *p = dpidbuf;
               char *q;
@@ -741,6 +745,31 @@
 {
   return fprintf(f, ToText()) > 0;
 }
+void cChannel::SetPreferredAlang(int count)
+{
+           bool found = false;
+           PreferredApid=&apids[0];
+           if(count>1){
+             for (int k = 0; k < I18nNumLanguages && Setup.EPGLanguages[k] >= 0; k++){
+              for(int j = 0;j<count;j++){
+               if(Setup.EPGLanguages[k]==I18nLanguageIndex(alangs[j])){
+                 PreferredApid = &apids[j];
+                 if(apids[j+1]==apids[j]){
+                   audiochannel=1;
+                 }else if((j>0) && (apids[j-1]==apids[j])){
+                   audiochannel=2;
+                 }
+                 //isyslog("found preferred lang '%s' apid %d",alangs[j],*PreferredApid);
+                 found = true;
+                 break;
+               }else if(j==count) found=true;
+              }//for
+               if (found) break;
+             }//for
+           }//if
+}
 
 // -- cChannels --------------------------------------------------------------
 
diff -ruN vdr-1.3.12/channels.h vdr-1.3.12-preffered/channels.h
--- vdr-1.3.12/channels.h	2004-04-03 15:40:47.000000000 +0200
+++ vdr-1.3.12-preffered/channels.h	2004-08-11 01:13:24.000000000 +0200
@@ -120,6 +120,7 @@
   cChannel *refChannel;
   const char *ParametersToString(void);
   bool StringToParameters(const char *s);
+  int *PreferredApid;
 public:
   cChannel(void);
   cChannel(const cChannel &Channel);
@@ -131,12 +132,13 @@
   const char *Name(void) const { return name; }
   int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf'
   int Transponder(void) const;                    ///< Returns the transponder frequency in MHz, plus the polarization in case of sat
+  int audiochannel;
   static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization
   int Source(void) const { return source; }
   int Srate(void) const { return srate; }
   int Vpid(void) const { return vpid; }
   int Ppid(void) const { return ppid; }
-  int Apid1(void) const { return apids[0]; }
+  int Apid1(void) const { return Setup.usePreferredApid ? *PreferredApid : apids[0]; }
   int Apid2(void) const { return apids[1]; }
   int Dpid1(void) const { return dpids[0]; }
   int Dpid2(void) const { return dpids[1]; }
@@ -147,6 +149,7 @@
   int Sid(void) const { return sid; }
   int Rid(void) const { return rid; }
   int Number(void) const { return number; }
+  void SetPreferredAlang(int count);
   void SetNumber(int Number) { number = Number; }
   bool GroupSep(void) const { return groupSep; }
   char Polarization(void) const { return polarization; }
diff -ruN vdr-1.3.12/config.c vdr-1.3.12-preffered/config.c
--- vdr-1.3.12/config.c	2004-05-16 14:43:55.000000000 +0200
+++ vdr-1.3.12-preffered/config.c	2004-08-11 01:13:24.000000000 +0200
@@ -275,6 +275,7 @@
   PausePriority = 10;
   PauseLifetime = 1;
   UseSubtitle = 1;
+  usePreferredApid = 0;
   UseVps = 0;
   VpsMargin = 120;
   RecordingDirs = 1;
@@ -428,6 +429,7 @@
   else if (!strcasecmp(Name, "PausePriority"))       PausePriority      = atoi(Value);
   else if (!strcasecmp(Name, "PauseLifetime"))       PauseLifetime      = atoi(Value);
   else if (!strcasecmp(Name, "UseSubtitle"))         UseSubtitle        = atoi(Value);
+  else if (!strcasecmp(Name, "UsePreferredApid"))    usePreferredApid   = atoi(Value);
   else if (!strcasecmp(Name, "UseVps"))              UseVps             = atoi(Value);
   else if (!strcasecmp(Name, "VpsMargin"))           VpsMargin          = atoi(Value);
   else if (!strcasecmp(Name, "RecordingDirs"))       RecordingDirs      = atoi(Value);
@@ -488,6 +490,7 @@
   Store("PausePriority",      PausePriority);
   Store("PauseLifetime",      PauseLifetime);
   Store("UseSubtitle",        UseSubtitle);
+  Store("UsePreferredApid",   usePreferredApid);
   Store("UseVps",             UseVps);
   Store("VpsMargin",          VpsMargin);
   Store("RecordingDirs",      RecordingDirs);
diff -ruN vdr-1.3.12/config.h vdr-1.3.12-preffered/config.h
--- vdr-1.3.12/config.h	2004-07-17 13:09:42.000000000 +0200
+++ vdr-1.3.12-preffered/config.h	2004-08-11 01:13:24.000000000 +0200
@@ -233,6 +233,7 @@
   int DefaultPriority, DefaultLifetime;
   int PausePriority, PauseLifetime;
   int UseSubtitle;
+  int usePreferredApid;
   int UseVps;
   int VpsMargin;
   int RecordingDirs;
diff -ruN vdr-1.3.12/device.c vdr-1.3.12-preffered/device.c
--- vdr-1.3.12/device.c	2004-06-19 10:51:05.000000000 +0200
+++ vdr-1.3.12-preffered/device.c	2004-08-11 01:13:24.000000000 +0200
@@ -49,7 +49,7 @@
   patFilter = NULL;
   sdtFilter = NULL;
   nitFilter = NULL;
-
+  currentaudiochannel = 0;
   ciHandler = NULL;
   player = NULL;
 
@@ -388,14 +388,20 @@
            dsyslog("skipped channel %d", first);
         else if (d)
            dsyslog("skipped channels %d..%d", first, n - sgn(d));
-        if (PrimaryDevice()->SwitchChannel(channel, true))
+        if (PrimaryDevice()->SwitchChannel(channel, true)){
+	   PrimaryDevice()->SelectAudioChannel(channel->audiochannel);
            result = true;
-        }
+	   }
+	}
      else if (n != first)
         Skins.Message(mtError, tr("Channel not available!"));
      }
   return result;
 }
+void cDevice::SelectAudioChannel(int achannel)
+{
+  SelectAudioChannelDevice(achannel);
+}
 
 eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
 {
@@ -471,6 +477,8 @@
 void cDevice::SetVolumeDevice(int Volume)
 {
 }
+void cDevice::SelectAudioChannelDevice(int achannel){
+}
 
 int cDevice::NumAudioTracksDevice(void) const
 {
diff -ruN vdr-1.3.12/device.h vdr-1.3.12-preffered/device.h
--- vdr-1.3.12/device.h	2004-06-19 10:50:37.000000000 +0200
+++ vdr-1.3.12-preffered/device.h	2004-08-11 01:13:24.000000000 +0200
@@ -286,6 +286,7 @@
   bool mute;
   int volume;
 protected:
+  int currentaudiochannel;
   virtual void SetVolumeDevice(int Volume);
        ///< Sets the audio volume on this device (Volume = 0...255).
   virtual int NumAudioTracksDevice(void) const;
@@ -309,6 +310,8 @@
        ///< Sets the current audio track to the given value, which should be within the
        ///< range of the list returned by a previous call to GetAudioTracksDevice()
        ///< (otherwise nothing will happen).
+  virtual void SelectAudioChannelDevice(int achannel);
+       ///< selects an audiochannel stereo=0 left=1 right=2
 public:
   bool IsMute(void) const { return mute; }
   bool ToggleMute(void);
@@ -316,6 +319,7 @@
   void SetVolume(int Volume, bool Absolute = false);
        ///< Sets the volume to the given value, either absolutely or relative to
        ///< the current volume.
+  void SelectAudioChannel(int achannel);
   static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX???
   int NumAudioTracks(void) const;
        ///< Returns the number of audio tracks that are currently available on this
diff -ruN vdr-1.3.12/dvbdevice.c vdr-1.3.12-preffered/dvbdevice.c
--- vdr-1.3.12/dvbdevice.c	2004-06-19 11:33:42.000000000 +0200
+++ vdr-1.3.12-preffered/dvbdevice.c	2004-08-11 01:13:24.000000000 +0200
@@ -777,6 +777,17 @@
   return true;
 }
 
+void cDvbDevice::SelectAudioChannelDevice(int achannel)
+{
+  if(Setup.usePreferredApid && achannel!=0){
+     CHECK(ioctl(fd_audio, AUDIO_CHANNEL_SELECT,achannel));
+    // currentaudiochannel = achannel;
+  }//else if(currentaudiochannel!=0){
+     //CHECK(ioctl(fd_audio, AUDIO_CHANNEL_SELECT,0));
+     //currentaudiochannel = 0;
+  //}
+  currentaudiochannel = achannel;
+}
 bool cDvbDevice::HasLock(void)
 {
   return dvbTuner ? dvbTuner->Locked() : false;
diff -ruN vdr-1.3.12/dvbdevice.h vdr-1.3.12-preffered/dvbdevice.h
--- vdr-1.3.12/dvbdevice.h	2004-06-19 10:51:33.000000000 +0200
+++ vdr-1.3.12-preffered/dvbdevice.h	2004-08-11 01:13:24.000000000 +0200
@@ -95,6 +95,7 @@
 private:
   int aPid1, aPid2;
 protected:
+  virtual void SelectAudioChannelDevice(int achannel);
   virtual void SetVolumeDevice(int Volume);
   virtual int NumAudioTracksDevice(void) const;
   virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
diff -ruN vdr-1.3.12/libsi/descriptor.c vdr-1.3.12-preffered/libsi/descriptor.c
--- vdr-1.3.12/libsi/descriptor.c	2004-06-06 16:47:30.000000000 +0200
+++ vdr-1.3.12-preffered/libsi/descriptor.c	2004-08-11 01:13:24.000000000 +0200
@@ -662,11 +662,27 @@
 
 void ISO639LanguageDescriptor::Parse() {
    unsigned int offset=0;
-   data.setPointerAndOffset<const descr_iso_639_language>(s, offset);
-   languageCode[0]=s->lang_code1;
-   languageCode[1]=s->lang_code2;
-   languageCode[2]=s->lang_code3;
-   languageCode[3]=0;
+   if (getLength()>6){
+     data.setPointerAndOffset<const descr_non_iso_639_language>(ns, offset);
+     languageCode[0]=ns->lang_code1;
+     languageCode[1]=ns->lang_code2;
+     languageCode[2]=ns->lang_code3;
+     languageCode[3]=0;
+     languageCode2[0]=ns->lang_code4;
+     languageCode2[1]=ns->lang_code5;
+     languageCode2[2]=ns->lang_code6;
+     languageCode2[3]=0;
+   }else {
+     data.setPointerAndOffset<const descr_iso_639_language>(s, offset);
+     languageCode[0]=s->lang_code1;
+     languageCode[1]=s->lang_code2;
+     languageCode[2]=s->lang_code3;
+     languageCode[3]=0;
+     languageCode2[0]='-';
+     languageCode2[1]='-';
+     languageCode2[2]='-';
+     languageCode2[3]=0;
+   }
 }
 
 void PDCDescriptor::Parse() {
diff -ruN vdr-1.3.12/libsi/descriptor.h vdr-1.3.12-preffered/libsi/descriptor.h
--- vdr-1.3.12/libsi/descriptor.h	2004-06-06 15:51:29.000000000 +0200
+++ vdr-1.3.12-preffered/libsi/descriptor.h	2004-08-11 01:13:24.000000000 +0200
@@ -393,10 +393,12 @@
 class ISO639LanguageDescriptor : public Descriptor {
 public:
    char languageCode[4];
+   char languageCode2[4];
 protected:
    virtual void Parse();
 private:
    const descr_iso_639_language *s;
+   const descr_non_iso_639_language *ns;
 };
 
 class PDCDescriptor : public Descriptor {
diff -ruN vdr-1.3.12/libsi/headers.h vdr-1.3.12-preffered/libsi/headers.h
--- vdr-1.3.12/libsi/headers.h	2004-02-22 12:12:46.000000000 +0100
+++ vdr-1.3.12-preffered/libsi/headers.h	2004-08-11 01:13:24.000000000 +0200
@@ -825,6 +825,19 @@
    u_char lang_code2                             :8;
    u_char lang_code3                             :8;
 };
+#define DESCR_NON_ISO_639_LANGUAGE_LEN 9
+struct descr_non_iso_639_language {
+   u_char descriptor_tag                         :8;
+   u_char descriptor_length                      :8;
+   u_char lang_code1                             :8;
+   u_char lang_code2                             :8;
+   u_char lang_code3                             :8;
+   u_char audio_type                             :8;
+   u_char lang_code4                             :8;
+   u_char lang_code5                             :8;
+   u_char lang_code6                             :8;
+};
+
 
 /* 0x13 carousel_identifier_descriptor */
 
diff -ruN vdr-1.3.12/menu.c vdr-1.3.12-preffered/menu.c
--- vdr-1.3.12/menu.c	2004-06-13 22:26:51.000000000 +0200
+++ vdr-1.3.12-preffered/menu.c	2004-08-11 01:13:24.000000000 +0200
@@ -1798,6 +1798,7 @@
   Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"),      &data.EPGScanTimeout));
   Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"),          &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL));
   Add(new cMenuEditIntItem( tr("Setup.EPG$EPG linger time (min)"),     &data.EPGLinger, 0));
+  Add(new cMenuEditBoolItem(tr("Setup.EPG$Use preferred audio language"),        &data.usePreferredApid));
   Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"),           &data.SetSystemTime));
   if (data.SetSystemTime)
      Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder, &data.TimeSource));
diff -ruN vdr-1.3.12/pat.c vdr-1.3.12-preffered/pat.c
--- vdr-1.3.12/pat.c	2004-05-23 11:29:04.000000000 +0200
+++ vdr-1.3.12-preffered/pat.c	2004-08-11 01:13:24.000000000 +0200
@@ -352,7 +352,13 @@
                                     if (*ld->languageCode != '-') { // some use "---" to indicate "none"
                                        strn0cpy(ALangs[NumApids], I18nNormalizeLanguageCode(ld->languageCode), 4);
                                        ALangs[NumApids][4] = 0;
-                                       }
+                                       if(*ld->languageCode2 != '-'){
+                                         NumApids++;
+                                         Apids[NumApids]=Apids[NumApids-1];
+                                         strn0cpy(ALangs[NumApids], I18nNormalizeLanguageCode(ld->languageCode2), 4);
+                                         ALangs[NumApids][4] =  0;  
+                                       } 
+                                      }
                                     }
                                     break;
                                default: ;
diff -ruN vdr-1.3.12/skinsttng.c vdr-1.3.12-preffered/skinsttng.c
--- vdr-1.3.12/skinsttng.c	2004-07-18 13:32:42.000000000 +0200
+++ vdr-1.3.12-preffered/skinsttng.c	2004-08-11 01:13:24.000000000 +0200
@@ -20,6 +20,7 @@
 #include "symbols/arrowdown.xpm"
 #include "symbols/arrowup.xpm"
 #include "symbols/audio.xpm"
+#include "symbols/stereo.xpm"
 #include "symbols/dolbydigital.xpm"
 #include "symbols/encrypted.xpm"
 #include "symbols/ffwd.xpm"
@@ -127,7 +128,7 @@
   bool message;
   const cEvent *present;
   int lastSeen;
-  static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
+  static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmStereo, bmEncrypted, bmRecording;
 public:
   cSkinSTTNGDisplayChannel(bool WithInfo);
   virtual ~cSkinSTTNGDisplayChannel();
@@ -140,7 +141,9 @@
 cBitmap cSkinSTTNGDisplayChannel::bmTeletext(teletext_xpm);
 cBitmap cSkinSTTNGDisplayChannel::bmRadio(radio_xpm);
 cBitmap cSkinSTTNGDisplayChannel::bmAudio(audio_xpm);
-cBitmap cSkinSTTNGDisplayChannel::bmDolbyDigital(dolbydigital_xpm);
+//cBitmap cSkinSTTNGDisplayChannel::bmDolbyDigital(dolbydigital_xpm);
+cBitmap cSkinSTTNGDisplayChannel::bmStereo(dolbydigital_xpm);
+cBitmap cSkinSTTNGDisplayChannel::bmDolbyDigital(mydolbydigital_xpm);
 cBitmap cSkinSTTNGDisplayChannel::bmEncrypted(encrypted_xpm);
 cBitmap cSkinSTTNGDisplayChannel::bmRecording(recording_xpm);
 
@@ -232,10 +235,18 @@
      osd->DrawBitmap(x, y0 + (y1 - y0 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor);
      x -= bmEncrypted.Width() + d;
      osd->DrawBitmap(x, y0 + (y1 - y0 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
-     x -= bmDolbyDigital.Width() + d;
-     osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid1() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
+     if (Channel->Dpid1()){ 
+   	x -= bmDolbyDigital.Width() + d;
+	osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(clrChannelSymbolOn), frameColor);   
+    }else {
+	x -= bmStereo.Width() + d;
+	osd->DrawBitmap(x, y0 + (y1 - y0 - bmStereo.Height()) / 2, bmStereo, Theme.Color(Channel->audiochannel ? clrChannelSymbolOff : clrChannelSymbolOn), frameColor);
+							       
+   }
+     //x -= bmDolbyDigital.Width() + d;
+     //osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid1() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
      x -= bmAudio.Width() + d;
-     osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid2() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
+     osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(!Channel->audiochannel ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
      if (Channel->Vpid()) {
         x -= bmTeletext.Width() + d;
         osd->DrawBitmap(x, y0 + (y1 - y0 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
diff -ruN vdr-1.3.12/symbols/dolbydigital.xpm vdr-1.3.12-preffered/symbols/dolbydigital.xpm
--- vdr-1.3.12/symbols/dolbydigital.xpm	2004-04-25 17:02:18.000000000 +0200
+++ vdr-1.3.12-preffered/symbols/dolbydigital.xpm	2004-08-11 01:13:24.000000000 +0200
@@ -1,23 +1,22 @@
-/* XPM */
-static char * dolbydigital_xpm[] = {
+static char * mydolbydigital_xpm[] = {
 "27 18 2 1",
 ".	c #FFFFFF",
 "+	c #000000",
 "...........................",
 "...........................",
 "..+++++++++++.+++++++++++..",
-"..++.++++++++.++++++++.++..",
 "..++...++++++.++++++...++..",
 "..++.....++++.++++.....++..",
-"..++......+++.+++......++..",
 "..++.......++.++.......++..",
 "..++.......++.++.......++..",
 "..++.......++.++.......++..",
-"..++.......++.++.......++..",
-"..++......+++.+++......++..",
 "..++.....++++.++++.....++..",
 "..++...++++++.++++++...++..",
-"..++.++++++++.++++++++.++..",
 "..+++++++++++.+++++++++++..",
 "...........................",
+"..++..+..++.+.+++..+..+....",
+"..+.+.+.+...+..+..+.+.+....",
+"..+.+.+.+.+.+..+..+++.+....",
+"..++..+..++.+..+..+.+.+++..",
+"...........................",
 "..........................."};
diff -ruN vdr-1.3.12/symbols/stereo.xpm vdr-1.3.12-preffered/symbols/stereo.xpm
--- vdr-1.3.12/symbols/stereo.xpm	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.3.12-preffered/symbols/stereo.xpm	2004-08-11 01:13:24.000000000 +0200
@@ -0,0 +1,23 @@
+/* XPM */
+static char * dolbydigital_xpm[] = {
+"27 18 2 1",
+".	c #FFFFFF",
+"+	c #000000",
+"...........................",
+"...........................",
+"..+++++++++++.+++++++++++..",
+"..++.++++++++.++++++++.++..",
+"..++...++++++.++++++...++..",
+"..++.....++++.++++.....++..",
+"..++......+++.+++......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++.......++.++.......++..",
+"..++......+++.+++......++..",
+"..++.....++++.++++.....++..",
+"..++...++++++.++++++...++..",
+"..++.++++++++.++++++++.++..",
+"..+++++++++++.+++++++++++..",
+"...........................",
+"..........................."};

Home | Main Index | Thread Index