]> git.sesse.net Git - vlc/commitdiff
atmo: add support for new device fnordlicht
authorKai Lauterbach <lauterbach.kai@web.de>
Tue, 1 Jun 2010 19:26:36 +0000 (21:26 +0200)
committerAndré Weber <atmo@videolan.org>
Tue, 1 Jun 2010 19:28:37 +0000 (21:28 +0200)
Fnordlicht - is a serial device with up to four channels
- http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
- http://github.com/fd0/fnordlicht/

Signed-off-by: André Weber <atmo@videolan.org>
modules/video_filter/Modules.am
modules/video_filter/atmo/AtmoConfig.cpp
modules/video_filter/atmo/AtmoConfig.h
modules/video_filter/atmo/AtmoDefs.h
modules/video_filter/atmo/AtmoTools.cpp
modules/video_filter/atmo/FnordlichtConnection.cpp [new file with mode: 0644]
modules/video_filter/atmo/FnordlichtConnection.h [new file with mode: 0644]
modules/video_filter/atmo/README.txt
modules/video_filter/atmo/atmo.cpp

index b6c13773deea3fe5be91e2a038578c24a92d16a2..ea46c31c6801474a8be43106df7359dbcedf8123 100644 (file)
@@ -71,6 +71,7 @@ SOURCES_atmo = atmo/atmo.cpp \
        atmo/DmxTools.cpp atmo/DmxTools.h \
        atmo/AtmoMultiConnection.cpp atmo/AtmoMultiConnection.h \
        atmo/MoMoConnection.cpp atmo/MoMoConnection.h \
+       atmo/FnordlichtConnection.cpp atmo/FnordlichtConnection.h \
        atmo/AtmoPacketQueue.cpp atmo/AtmoPacketQueue.h
 SOURCES_gradfun = gradfun.c gradfun.h
 noinst_HEADERS = filter_picture.h
index ec6c519587c0c5c6057f6e0493cd65079a4d7195..e5273ddd5768731c4507c29363290936853a9c32 100644 (file)
@@ -44,6 +44,10 @@ CAtmoConfig::CAtmoConfig()
   m_AtmoZoneDefCount = -1;
   m_DMX_BaseChannels = NULL;
 
+  m_chWhiteAdj_Red   = NULL;
+  m_chWhiteAdj_Green = NULL;
+  m_chWhiteAdj_Blue  = NULL;
+
   LoadDefaults();
 }
 
@@ -59,6 +63,10 @@ CAtmoConfig::~CAtmoConfig() {
      m_ZoneDefinitions = NULL;
    }
 
+   delete []m_chWhiteAdj_Red;
+   delete []m_chWhiteAdj_Green;
+   delete []m_chWhiteAdj_Blue;
+
    free( m_DMX_BaseChannels );
 
 #if defined (_ATMO_VLC_PLUGIN_)
@@ -99,8 +107,6 @@ void CAtmoConfig::LoadDefaults() {
 
     m_UpdateEdgeWeightningFlag = 0;
 
-
-
     m_Software_gamma_mode = agcNone;
     m_Software_gamma_red    = 10;
     m_Software_gamma_green  = 10;
@@ -112,6 +118,17 @@ void CAtmoConfig::LoadDefaults() {
     m_WhiteAdjustment_Blue   = 255;
        m_UseSoftwareWhiteAdj    = 1;
 
+    m_WhiteAdjPerChannel = ATMO_FALSE;
+    m_chWhiteAdj_Count = 0;
+
+    delete []m_chWhiteAdj_Red;
+    delete []m_chWhiteAdj_Green;
+    delete []m_chWhiteAdj_Blue;
+
+    m_chWhiteAdj_Red   = NULL;
+    m_chWhiteAdj_Green = NULL;
+    m_chWhiteAdj_Blue  = NULL;
+
        m_ColorChanger_iSteps    = 50;
        m_ColorChanger_iDelay    = 25;
 
@@ -145,6 +162,7 @@ void CAtmoConfig::LoadDefaults() {
     m_LiveView_DisplayNr        = 0;
     m_LiveView_FrameDelay       = 30;
     m_LiveView_GDI_FrameRate    = 25;
+       m_LiveView_RowsPerFrame     = 0;
 
 
     m_Hardware_global_gamma    = 128;
@@ -161,6 +179,7 @@ void CAtmoConfig::LoadDefaults() {
     m_DMX_RGB_Channels        = 5; // so wie atmolight
 
     m_MoMo_Channels           = 3; // default momo, there exists also a 4 ch version!
+    m_Fnordlicht_Amount       = 2; // default fnordlicht, there are 2 fnordlicht's!
 
     m_ZonesTopCount            = 1;
     m_ZonesBottomCount         = 1;
@@ -168,7 +187,6 @@ void CAtmoConfig::LoadDefaults() {
     m_ZoneSummary              = ATMO_FALSE;
     UpdateZoneCount();
 
-
     clearAllChannelMappings();
     m_CurrentChannelAssignment = 0;
     CAtmoChannelAssignment *temp = new CAtmoChannelAssignment();
@@ -201,6 +219,25 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
     this->m_WhiteAdjustment_Blue     = pAtmoConfigSrc->m_WhiteAdjustment_Blue;
     this->m_UseSoftwareWhiteAdj      = pAtmoConfigSrc->m_UseSoftwareWhiteAdj;
 
+    this->m_WhiteAdjPerChannel       = pAtmoConfigSrc->m_WhiteAdjPerChannel;
+    this->m_chWhiteAdj_Count         = pAtmoConfigSrc->m_chWhiteAdj_Count;
+    delete []m_chWhiteAdj_Red;
+    delete []m_chWhiteAdj_Green;
+    delete []m_chWhiteAdj_Blue;
+    if(m_chWhiteAdj_Count > 0)
+    {
+       m_chWhiteAdj_Red   = new int[ m_chWhiteAdj_Count ];
+       m_chWhiteAdj_Green = new int[ m_chWhiteAdj_Count ];
+       m_chWhiteAdj_Blue  = new int[ m_chWhiteAdj_Count ];
+       memcpy(m_chWhiteAdj_Red, pAtmoConfigSrc->m_chWhiteAdj_Red, sizeof(int) * m_chWhiteAdj_Count);
+       memcpy(m_chWhiteAdj_Green, pAtmoConfigSrc->m_chWhiteAdj_Green, sizeof(int) * m_chWhiteAdj_Count);
+       memcpy(m_chWhiteAdj_Blue, pAtmoConfigSrc->m_chWhiteAdj_Blue, sizeof(int) * m_chWhiteAdj_Count);
+    } else {
+       m_chWhiteAdj_Red   = NULL;
+       m_chWhiteAdj_Green = NULL;
+       m_chWhiteAdj_Blue  = NULL;
+    }
+
     this->m_IsSetShutdownColor       = pAtmoConfigSrc->m_IsSetShutdownColor;
     this->m_ShutdownColor_Red        = pAtmoConfigSrc->m_ShutdownColor_Red;
     this->m_ShutdownColor_Green      = pAtmoConfigSrc->m_ShutdownColor_Green;
@@ -223,7 +260,6 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
 
     this->m_show_statistics               = pAtmoConfigSrc->m_show_statistics;
 
-
     this->m_LiveView_EdgeWeighting  =  pAtmoConfigSrc->m_LiveView_EdgeWeighting;
     this->m_LiveView_BrightCorrect  =  pAtmoConfigSrc->m_LiveView_BrightCorrect;
     this->m_LiveView_DarknessLimit  =  pAtmoConfigSrc->m_LiveView_DarknessLimit;
@@ -236,6 +272,7 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
     this->m_LiveView_DisplayNr        = pAtmoConfigSrc->m_LiveView_DisplayNr;
     this->m_LiveView_FrameDelay       = pAtmoConfigSrc->m_LiveView_FrameDelay;
     this->m_LiveView_GDI_FrameRate    = pAtmoConfigSrc->m_LiveView_GDI_FrameRate;
+    this->m_LiveView_RowsPerFrame   =  pAtmoConfigSrc->m_LiveView_RowsPerFrame;
 
     this->m_ZonesTopCount             = pAtmoConfigSrc->m_ZonesTopCount;
     this->m_ZonesBottomCount          = pAtmoConfigSrc->m_ZonesBottomCount;
@@ -255,6 +292,8 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
 
     this->m_MoMo_Channels            = pAtmoConfigSrc->m_MoMo_Channels;
 
+    this->m_Fnordlicht_Amount        = pAtmoConfigSrc->m_Fnordlicht_Amount;
+
     this->m_CurrentChannelAssignment = pAtmoConfigSrc->m_CurrentChannelAssignment;
 
     clearChannelMappings();
@@ -278,8 +317,6 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
     UpdateZoneDefinitionCount();
 }
 
-
-
 int CAtmoConfig::getNumChannelAssignments() {
     int z=0;
     for(int i=0;i<10;i++)
@@ -336,8 +373,6 @@ void CAtmoConfig::UpdateZoneCount()
      m_computed_zones_count++;
 }
 
-
-
 int CAtmoConfig::getZoneCount()
 {
     return(m_computed_zones_count);
@@ -423,3 +458,50 @@ void CAtmoConfig::setDMX_BaseChannels(char *channels)
      m_DMX_BaseChannels = strdup(channels);
 }
 
+void CAtmoConfig::getChannelWhiteAdj(int channel,int &red,int &green,int &blue)
+{
+  if(channel >= m_chWhiteAdj_Count)
+  {
+     red = 256;
+     green = 256;
+     blue = 256;
+
+  } else {
+
+    red   = m_chWhiteAdj_Red[ channel ];
+    green = m_chWhiteAdj_Green[ channel ];
+    blue  = m_chWhiteAdj_Blue[ channel ];
+
+  }
+}
+
+void CAtmoConfig::setChannelWhiteAdj(int channel,int red,int green,int blue)
+{
+    if(channel >= m_chWhiteAdj_Count)
+    {
+       int *tmp = new int[channel+1];
+       if(m_chWhiteAdj_Red)
+          memcpy( tmp, m_chWhiteAdj_Red, m_chWhiteAdj_Count * sizeof(int) );
+       delete []m_chWhiteAdj_Red;
+       m_chWhiteAdj_Red = tmp;
+
+       tmp = new int[channel + 1];
+       if(m_chWhiteAdj_Green)
+          memcpy( tmp, m_chWhiteAdj_Green, m_chWhiteAdj_Count * sizeof(int) );
+       delete []m_chWhiteAdj_Green;
+       m_chWhiteAdj_Green = tmp;
+
+       tmp = new int[channel + 1];
+       if(m_chWhiteAdj_Blue)
+          memcpy( tmp, m_chWhiteAdj_Blue, m_chWhiteAdj_Count * sizeof(int) );
+       delete []m_chWhiteAdj_Blue;
+       m_chWhiteAdj_Blue = tmp;
+
+       m_chWhiteAdj_Count = channel + 1;
+   }
+
+   m_chWhiteAdj_Red[channel]   = red;
+   m_chWhiteAdj_Green[channel] = green;
+   m_chWhiteAdj_Blue[channel]  = blue;
+
+}
index 656c20ed72135e350d9b6c1973dee29fb036dc03..d3dd961e5009c7b83685e8cf6296075187501f9c 100644 (file)
 #   include <string.h>
 #endif
 
-
 class CAtmoConfig {
 
     protected:
-          int m_IsShowConfigDialog;    
+          int m_IsShowConfigDialog;
 #if defined(_ATMO_VLC_PLUGIN_)
        char *m_devicename;
        char *m_devicenames[3]; // additional Devices ?
@@ -42,6 +41,12 @@ class CAtmoConfig {
        int m_WhiteAdjustment_Green;
        int m_WhiteAdjustment_Blue;
 
+       ATMO_BOOL m_WhiteAdjPerChannel;
+       int  m_chWhiteAdj_Count;
+       int *m_chWhiteAdj_Red;
+       int *m_chWhiteAdj_Green;
+       int *m_chWhiteAdj_Blue;
+
     protected:
        int m_IsSetShutdownColor;
           int m_ShutdownColor_Red;
@@ -76,7 +81,6 @@ class CAtmoConfig {
         CAtmoZoneDefinition **m_ZoneDefinitions;
         int m_AtmoZoneDefCount;
 
-
         /*
           zone layout description for generating the default Zone weightning
         */
@@ -94,7 +98,6 @@ class CAtmoConfig {
     public:
         int getZoneCount();
 
-
     protected:
         /* Live View Parameters (most interesting) */
         AtmoFilterMode m_LiveViewFilterMode;
@@ -104,6 +107,9 @@ class CAtmoConfig {
 
         ATMO_BOOL m_show_statistics;
 
+               // number of rows to process each frame
+               int m_LiveView_RowsPerFrame;
+
         // weighting of distance to edge
         int m_LiveView_EdgeWeighting; //  = 8;
         // brightness correction
@@ -154,6 +160,9 @@ class CAtmoConfig {
     protected:
          int m_MoMo_Channels;
 
+    protected:
+         int m_Fnordlicht_Amount;
+
     protected:
          AtmoGammaCorrect m_Software_gamma_mode;
 
@@ -165,7 +174,6 @@ class CAtmoConfig {
     public:
         volatile int m_UpdateEdgeWeightningFlag;
 
-
     public:
        CAtmoConfig();
        virtual ~CAtmoConfig();
@@ -210,6 +218,13 @@ class CAtmoConfig {
         ATMO_BOOL isUseSoftwareWhiteAdj() { return m_UseSoftwareWhiteAdj; }
         void setUseSoftwareWhiteAdj(ATMO_BOOL value) { m_UseSoftwareWhiteAdj = value; }
 
+/* White ADJ per Channel settings */
+        ATMO_BOOL isWhiteAdjPerChannel() { return  m_WhiteAdjPerChannel; }
+        void setWhiteAdjPerChannel( ATMO_BOOL value) { m_WhiteAdjPerChannel = value; }
+
+        void setChannelWhiteAdj(int channel,int red,int green,int blue);
+        void getChannelWhiteAdj(int channel,int &red,int &green,int &blue);
+
         int isSetShutdownColor()     { return m_IsSetShutdownColor; }
         void SetSetShutdownColor(int value) { m_IsSetShutdownColor = value; }
         int getShutdownColor_Red()   { return m_ShutdownColor_Red; }
@@ -236,7 +251,6 @@ class CAtmoConfig {
         int getStaticColor_Blue()  { return m_StaticColor_Blue;  }
         void  setStaticColor_Blue(int value) { m_StaticColor_Blue=value; }
 
-
         AtmoConnectionType getConnectionType() { return m_eAtmoConnectionType; }
         void setConnectionType(AtmoConnectionType value) { m_eAtmoConnectionType = value; }
 
@@ -258,7 +272,10 @@ class CAtmoConfig {
         int getLiveView_EdgeWeighting() { return m_LiveView_EdgeWeighting; }
         void setLiveView_EdgeWeighting(int value) { m_LiveView_EdgeWeighting=value; }
 
-        int getLiveView_BrightCorrect() { return m_LiveView_BrightCorrect; }
+        int getLiveView_RowsPerFrame() { return m_LiveView_RowsPerFrame; }
+        void setLiveView_RowsPerFrame(int value) { m_LiveView_RowsPerFrame=value; }
+
+               int getLiveView_BrightCorrect() { return m_LiveView_BrightCorrect; }
         void setLiveView_BrightCorrect(int value) { m_LiveView_BrightCorrect=value; }
 
         int getLiveView_DarknessLimit() { return m_LiveView_DarknessLimit; }
@@ -312,7 +329,6 @@ class CAtmoConfig {
         int getHardware_gamma_blue() { return m_Hardware_gamma_blue; }
         void setHardware_gamma_blue(int value) { m_Hardware_gamma_blue=value; }
 
-
         AtmoGammaCorrect getSoftware_gamma_mode() { return m_Software_gamma_mode; }
         int getSoftware_gamma_red() { return m_Software_gamma_red; }
         int getSoftware_gamma_green() { return m_Software_gamma_green; }
@@ -359,6 +375,9 @@ class CAtmoConfig {
         int getMoMo_Channels() { return m_MoMo_Channels; }
         void setMoMo_Channels(int chCount) { m_MoMo_Channels = chCount; }
 
+        int getFnordlicht_Amount() { return m_Fnordlicht_Amount; }
+        void setFnordlicht_Amount(int fnordlichtAmount) { m_Fnordlicht_Amount = fnordlichtAmount; }
+
 };
 
 #endif
index ed48e880f31caf5f65c1bb5f92de9b3619dc5e9b..739978a6fdc82becf4b8e0946b0b402cdff6616e 100644 (file)
@@ -114,7 +114,8 @@ enum AtmoConnectionType
       actNUL = 3,
       actMultiAtmo = 4,
       actMondolight = 5,
-      actMoMoLight  = 6
+      actMoMoLight = 6,
+      actFnordlicht = 7
 };
 static const char *AtmoDeviceTypes[] = {
       "Atmo-Classic",
@@ -123,10 +124,10 @@ static const char *AtmoDeviceTypes[] = {
       "Nul-Device",
       "Multi-Atmo",
       "Mondolight",
-      "MoMoLight"
-
+      "MoMoLight",
+      "Fnordlicht"
   };
-#define ATMO_DEVICE_COUNT 7
+#define ATMO_DEVICE_COUNT 8
 
 #if defined(_ATMO_VLC_PLUGIN_)
 enum EffectMode {
index 69e07739ccd2e6a66394e24684b53c4457cff89e..e96bb32315190cff7bde02adf3da776730d4b988 100644 (file)
@@ -13,6 +13,7 @@
 #include "AtmoDmxSerialConnection.h"
 #include "AtmoMultiConnection.h"
 #include "MoMoConnection.h"
+#include "FnordlichtConnection.h"
 #include "AtmoExternalCaptureInput.h"
 #include <math.h>
 
@@ -27,7 +28,6 @@
 #   include "AtmoGdiDisplayCaptureInput.h"
 #endif
 
-
 CAtmoTools::CAtmoTools(void)
 {
 }
@@ -40,7 +40,6 @@ void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
 {
     pDynData->LockCriticalSection();
 
-
     CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
     CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
     if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) {
@@ -403,6 +402,24 @@ ATMO_BOOL CAtmoTools::RecreateConnection(CAtmoDynData *pDynData)
                return ATMO_TRUE;
            }
 
+           case actFnordlicht: {
+               CFnordlichtConnection *tempConnection = new CFnordlichtConnection( atmoConfig );
+               if(tempConnection->OpenConnection() == ATMO_FALSE) {
+                  pDynData->setAtmoConnection(tempConnection);
+                  pDynData->UnLockCriticalSection();
+                  return ATMO_FALSE;
+               }
+               pDynData->setAtmoConnection(tempConnection);
+               pDynData->ReloadZoneDefinitionBitmaps();
+
+               tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
+
+               CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
+
+               pDynData->UnLockCriticalSection();
+               return ATMO_TRUE;
+           }
+
            default: {
                pDynData->UnLockCriticalSection();
                return ATMO_FALSE;
diff --git a/modules/video_filter/atmo/FnordlichtConnection.cpp b/modules/video_filter/atmo/FnordlichtConnection.cpp
new file mode 100644 (file)
index 0000000..583a165
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * FnordlichtConnection.h: class to access a FnordlichtLight Hardware
+ * - the description could be found
+ * here: http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
+ *
+ * (C) Kai Lauterbach (klaute at gmail.com)
+ *
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+
+#include "AtmoDefs.h"
+#include "FnordlichtConnection.h"
+
+#if !defined(_ATMO_VLC_PLUGIN_)
+# include "FnordlichtConfigDialog.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+
+#if !defined(WIN32)
+#include <termios.h>
+#include <unistd.h>
+#endif
+
+CFnordlichtConnection::CFnordlichtConnection(CAtmoConfig *cfg)
+       : CAtmoConnection(cfg)
+{
+       m_hComport = INVALID_HANDLE_VALUE;
+}
+
+CFnordlichtConnection::~CFnordlichtConnection()
+{
+}
+
+ATMO_BOOL CFnordlichtConnection::OpenConnection()
+{
+#if defined(_ATMO_VLC_PLUGIN_)
+       char *serdevice = m_pAtmoConfig->getSerialDevice();
+       if ( !serdevice )
+               return ATMO_FALSE;
+#else
+       int portNummer = m_pAtmoConfig->getComport();
+       m_dwLastWin32Error = 0;
+       if ( portNummer < 1 )
+               return ATMO_FALSE; // make no real sense;-)
+#endif
+
+       CloseConnection();
+
+#if !defined(_ATMO_VLC_PLUGIN_)
+       char serdevice[16];  // com4294967295
+       sprintf(serdevice,"com%d",portNummer);
+#endif
+
+#if defined(WIN32)
+
+       m_hComport = CreateFile(serdevice,
+                                       GENERIC_WRITE, 0, NULL,
+                                       OPEN_EXISTING, 0, NULL);
+       if ( m_hComport == INVALID_HANDLE_VALUE )
+       {
+               // we have a problem here can't open com port...
+               // somebody else may use it?
+               // m_dwLastWin32Error = GetLastError();
+               return ATMO_FALSE;
+       }
+       /* change serial settings (Speed, stopbits etc.) */
+       DCB dcb; // für comport-parameter
+       dcb.DCBlength = sizeof(DCB);
+       GetCommState(m_hComport, &dcb); // ger current serialport settings
+       dcb.BaudRate = 19200;      // set speed
+       dcb.ByteSize = 8;                 // set databits
+       dcb.Parity   = NOPARITY;        // set parity
+       dcb.StopBits = ONESTOPBIT;   // set one stop bit
+       SetCommState(m_hComport, &dcb);    // apply settings
+
+#else
+
+       int bconst = B19200;
+       m_hComport = open(serdevice,O_RDWR |O_NOCTTY);
+       if ( m_hComport < 0 )
+               return ATMO_FALSE;
+
+       struct termios tio;
+       memset(&tio,0,sizeof(tio));
+       tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
+       tio.c_iflag = (INPCK | BRKINT);
+       cfsetispeed(&tio, bconst);
+       cfsetospeed(&tio, bconst);
+       if( ! tcsetattr(m_hComport, TCSANOW, &tio) )
+               tcflush(m_hComport, TCIOFLUSH);
+       else {
+               // can't change parms
+               close(m_hComport);
+               m_hComport = -1;
+               return false;
+       }
+
+#endif
+
+       // sync fnordlicht
+       if ( sync() )
+               // stop fading on all devices
+               if ( stop(255) )
+                       return true; // fnordlicht initialized...
+
+       return false; // something is going wrong...
+}
+
+void CFnordlichtConnection::CloseConnection()
+{
+       if ( m_hComport != INVALID_HANDLE_VALUE )
+       {
+               reset(255);
+
+#if defined(WIN32)
+               CloseHandle(m_hComport);
+#else
+               close(m_hComport);
+#endif
+               m_hComport = INVALID_HANDLE_VALUE;
+       }
+}
+
+ATMO_BOOL CFnordlichtConnection::isOpen(void)
+{
+       return (m_hComport != INVALID_HANDLE_VALUE);
+}
+
+ATMO_BOOL CFnordlichtConnection::HardwareWhiteAdjust(int global_gamma,
+                                                                                  int global_contrast,
+                                                                                  int contrast_red,
+                                                                                  int contrast_green,
+                                                                                  int contrast_blue,
+                                                                                  int gamma_red,
+                                                                                  int gamma_green,
+                                                                                  int gamma_blue,
+                                                                                  ATMO_BOOL storeToEeprom)
+{
+       return ATMO_FALSE; //no hardware adjust required
+}
+
+/*
+    def fade_rgb(addr, r, g, b, step, delay)
+          $dev.write addr.chr
+          $dev.write "\x01"
+          $dev.write step.chr
+          $dev.write delay.chr
+          $dev.write r.chr
+          $dev.write g.chr
+          $dev.write b.chr
+          $dev.write "\x00\x00\x00\x00\x00"
+          $dev.write "\x00\x00\x00"
+          $dev.flush
+    end
+*/
+ATMO_BOOL CFnordlichtConnection::SendData(pColorPacket data)
+{
+       if ( m_hComport == INVALID_HANDLE_VALUE )
+               return ATMO_FALSE;
+
+       int amount = getAmountFnordlichter();
+       unsigned char buffer[15];
+       memset(&buffer, 0, sizeof(buffer) ); // zero buffer
+       int iBytesWritten;
+
+       Lock();
+
+       buffer[1] = 0x01; // fade to rgb color
+       buffer[2] = 0x80; // in two steps
+       buffer[3] = 0x01; // 1ms pause between steps
+
+       // send all packages to all fnordlicht's
+       for( unsigned char i=0; i < amount; i++ )
+       {
+               int idx;
+               if ( m_ChannelAssignment && i < m_NumAssignedChannels )
+                       idx = m_ChannelAssignment[i];
+               else
+                       idx = -1; // no channel assigned to fnordlicht[i]
+
+               if( idx >= 0 && idx <= data->numColors )
+               {
+                       // fnordlicht address equals to a MoMo Channel
+                       buffer[0] = i; // fnordlicht address (0..254, 255 = broadcast)
+                       buffer[4] = data->zone[idx].r;
+                       buffer[5] = data->zone[idx].g;
+                       buffer[6] = data->zone[idx].b;
+               }
+
+#if defined(WIN32)
+               // send to COM-Port
+               WriteFile( m_hComport, buffer, sizeof(buffer),
+                                       (DWORD*)&iBytesWritten, NULL );
+#else
+               iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
+               tcflush(m_hComport, TCIOFLUSH);
+               tcdrain(m_hComport); // flush buffer
+#endif
+
+               if (iBytesWritten != sizeof(buffer))
+               {
+                       Unlock();
+                       return ATMO_FALSE; // shouldn't be...
+               }
+
+       }
+
+       Unlock();
+
+       return ATMO_TRUE;
+}
+
+
+ATMO_BOOL CFnordlichtConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
+{
+       if ( !ca )
+               return ATMO_FALSE;
+       ca->setSize( getAmountFnordlichter() );  // oder 4 ? depending on config!
+       ca->setZoneIndex(0, 0); // Zone 5
+       ca->setZoneIndex(1, 1);
+       ca->setZoneIndex(2, 2);
+       ca->setZoneIndex(3, 3);
+       return ATMO_TRUE;
+}
+
+int CFnordlichtConnection::getAmountFnordlichter()
+{
+   return m_pAtmoConfig->getFnordlicht_Amount();
+}
+
+/*
+    def sync(addr = 0)
+          1.upto(15) do
+                 $dev.write "\e"
+          end
+          $dev.write addr.chr
+          $dev.flush
+    end
+*/
+ATMO_BOOL CFnordlichtConnection::sync(void)
+{
+       if ( m_hComport == INVALID_HANDLE_VALUE )
+               return ATMO_FALSE;
+
+       unsigned char buffer[16];
+       int iBytesWritten;
+
+       Lock();
+
+       // fill buffer with 15 escape character
+       memset(&buffer, 0x1b, sizeof(buffer)-1);
+
+       buffer[sizeof(buffer)-1] = 0x00; // append one zero byte
+
+#if defined(WIN32)
+               // send to COM-Port
+               WriteFile( m_hComport, buffer, sizeof(buffer),
+                                       (DWORD*)&iBytesWritten, NULL );
+#else
+               iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
+               tcflush(m_hComport, TCIOFLUSH);
+               tcdrain(m_hComport); // flush buffer
+#endif
+
+       Unlock();
+
+       return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
+
+}
+
+/*
+    def stop(addr, fading = 1)
+          $dev.write addr.chr
+          $dev.write "\x08"
+          $dev.write fading.chr
+          $dev.write "\x00\x00\x00\x00"
+          $dev.write "\x00\x00\x00\x00\x00"
+          $dev.write "\x00\x00\x00"
+          $dev.flush
+    end
+*/
+ATMO_BOOL CFnordlichtConnection::stop(unsigned char addr)
+{
+       if(m_hComport == INVALID_HANDLE_VALUE)
+               return ATMO_FALSE;
+
+       unsigned char buffer[15];
+       memset(&buffer, 0, sizeof(buffer)); // zero buffer
+       int iBytesWritten;
+
+       Lock();
+
+       buffer[0] = addr; // fnordlicht address (255 = broadcast)
+       buffer[1] = 0x08; // stop command
+       buffer[2] = 1;    // fading
+
+#if defined(WIN32)
+               // send to COM-Port
+               WriteFile( m_hComport, buffer, sizeof(buffer),
+                                       (DWORD*)&iBytesWritten, NULL );
+#else
+               iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
+               tcflush(m_hComport, TCIOFLUSH);
+               tcdrain(m_hComport); // flush buffer
+#endif
+
+       Unlock();
+
+       return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
+}
+
+/*
+*/
+ATMO_BOOL CFnordlichtConnection::reset(unsigned char addr)
+{
+       if(m_hComport == INVALID_HANDLE_VALUE)
+               return ATMO_FALSE;
+
+       stop(255);
+
+       if ( sync() && start_bootloader(addr) )
+       {
+#if defined(_ATMO_VLC_PLUGIN_)
+        do_sleep(200000); // wait 200ms
+#else
+        do_sleep(200); // wait 200ms
+#endif
+               if ( sync() && boot_enter_application(addr) )
+                               return ATMO_TRUE;
+       }
+
+       return ATMO_FALSE;
+}
+
+/*
+    def start_bootloader(addr)
+        $dev.write(addr.chr)
+        $dev.write("\x80")
+        $dev.write("\x6b\x56\x27\xfc")
+        $dev.write("\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+        $dev.flush
+    end
+*/
+ATMO_BOOL CFnordlichtConnection::start_bootloader(unsigned char addr)
+{
+       if(m_hComport == INVALID_HANDLE_VALUE)
+               return ATMO_FALSE;
+
+       unsigned char buffer[15];
+       memset(&buffer, 0, sizeof(buffer)); // zero buffer
+       int iBytesWritten;
+
+       Lock();
+
+       buffer[0] = addr; // fnordlicht address (255 = broadcast)
+       buffer[1] = 0x80; // start_bootloader
+       buffer[2] = 0x6b;
+       buffer[3] = 0x56;
+       buffer[4] = 0x27;
+       buffer[5] = 0xfc;
+
+#if defined(WIN32)
+               // send to COM-Port
+               WriteFile( m_hComport, buffer, sizeof(buffer),
+                                       (DWORD*)&iBytesWritten, NULL );
+#else
+               iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
+               tcflush(m_hComport, TCIOFLUSH);
+               tcdrain(m_hComport); // flush buffer
+#endif
+
+       Unlock();
+
+       return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
+}
+
+/*
+    def boot_enter_application(addr)
+        $dev.write(addr.chr)
+        $dev.write("\x87")
+        $dev.write("\x00"*13)
+        $dev.flush
+    end
+*/
+ATMO_BOOL CFnordlichtConnection::boot_enter_application(unsigned char addr)
+{
+       if(m_hComport == INVALID_HANDLE_VALUE)
+               return ATMO_FALSE;
+
+       unsigned char buffer[15];
+       memset(&buffer, 0, sizeof(buffer)); // zero buffer
+       int iBytesWritten;
+
+       Lock();
+
+       buffer[0] = addr; // fnordlicht address (255 = broadcast)
+       buffer[1] = 0x87; // boot_ender_application command
+
+#if defined(WIN32)
+               // send to COM-Port
+               WriteFile( m_hComport, buffer, sizeof(buffer),
+                                       (DWORD*)&iBytesWritten, NULL );
+#else
+               iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
+               tcflush(m_hComport, TCIOFLUSH);
+               tcdrain(m_hComport); // flush buffer
+#endif
+
+       Unlock();
+
+       return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
+}
+
+#if !defined(_ATMO_VLC_PLUGIN_)
+
+char *CFnordlichtConnection::getChannelName(int ch)
+{
+       char buf[60];
+       if( ch < 0 ) return NULL;
+       if( ch >= getAmountFnordlichter() ) return NULL;
+
+       sprintf(buf,"Number [%d]",ch);
+       return strdup(buf);
+       // sorry asprintf is not defined on Visual Studio :)
+       // return (asprintf(&ret, "Number [%d]", ch) != -1) ? ret : NULL;
+
+}
+
+ATMO_BOOL CFnordlichtConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent,
+                                                                                                       CAtmoConfig *cfg)
+{
+       CFnordlichtConfigDialog *dlg = new CFnordlichtConfigDialog(hInst,
+                                                                                                                               parent,
+                                                                                                                               cfg);
+
+       INT_PTR result = dlg->ShowModal();
+
+       delete dlg;
+
+       if(result == IDOK)
+               return ATMO_TRUE;
+       else
+               return ATMO_FALSE;
+}
+
+#endif
+
diff --git a/modules/video_filter/atmo/FnordlichtConnection.h b/modules/video_filter/atmo/FnordlichtConnection.h
new file mode 100644 (file)
index 0000000..6a3fa13
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * FnordlichtConnection.h: class to access a FnordlichtLight Hardware
+ * - the description could be found
+ * here: http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
+ *
+ * (C) Kai Lauterbach (klaute at gmail.com)
+ *
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+#ifndef _FnordlichtConnection_h_
+#define _FnordlichtConnection_h_
+
+#include "AtmoDefs.h"
+#include "AtmoConnection.h"
+#include "AtmoConfig.h"
+
+#if defined(WIN32)
+#   include <windows.h>
+#endif
+
+
+class CFnordlichtConnection : public CAtmoConnection
+{
+       private:
+               HANDLE m_hComport;
+
+               ATMO_BOOL sync(void);
+               ATMO_BOOL stop(unsigned char addr);
+               ATMO_BOOL reset(unsigned char addr);
+               ATMO_BOOL start_bootloader(unsigned char addr);
+               ATMO_BOOL boot_enter_application(unsigned char addr);
+
+#if defined(WIN32)
+               DWORD  m_dwLastWin32Error;
+       public:
+               DWORD getLastError() { return m_dwLastWin32Error; }
+#endif
+
+       public:
+               CFnordlichtConnection (CAtmoConfig *cfg);
+               virtual ~CFnordlichtConnection (void);
+
+               virtual ATMO_BOOL OpenConnection();
+
+               virtual void CloseConnection();
+
+               virtual ATMO_BOOL isOpen(void);
+
+               virtual ATMO_BOOL SendData(pColorPacket data);
+
+               virtual ATMO_BOOL HardwareWhiteAdjust(int global_gamma,
+                                                                                       int global_contrast,
+                                                                                       int contrast_red,
+                                                                                       int contrast_green,
+                                                                                       int contrast_blue,
+                                                                                       int gamma_red,
+                                                                                       int gamma_green,
+                                                                                       int gamma_blue,
+                                                                                       ATMO_BOOL storeToEeprom);
+
+               virtual int getAmountFnordlichter();
+
+               virtual const char *getDevicePath() { return "fnordlicht"; }
+
+#if !defined(_ATMO_VLC_PLUGIN_)
+               virtual char *getChannelName(int ch);
+               virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent,
+                                                                                       CAtmoConfig *cfg);
+#endif
+
+               virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
+};
+
+#endif
index 4cf6595960c74119d02e0b73d06bf9aa8f865772..44f568944a371a6a5f9df4734b3caa00c2e33304 100644 (file)
-This piece of software is based on the software and descriptions mentioned below -\r
-\r
-\r
-(re)Written by:              Igor / Atmo (aka André Weber)  - WeberAndre@gmx.de\r
-                             Matthiaz    \r
-                             MacGyver2k\r
-\r
-if you need to contact one of us - come to www.vdr-portal.de \r
-\r
-http://www.vdr-portal.de/board/thread.php?threadid=59294 -- Description and Development of the Windows Software\r
-http://www.vdr-portal.de/board/thread.php?threadid=48574 -- Description and Development of the Hardware part\r
-\r
-=====================================================\r
-Info for Users on Vista or Windows 7 with active UAC!\r
-=====================================================\r
-for the first launch do it as Administrator with the following command line \r
-\r
-AtmoWinA.exe /register \r
-\r
-to create the required registry entries for the COM Objects, without\r
-these registry entries - the DirectShow Filter and also the VLC Plugin\r
-will not work.\r
-If anything went fine you should see the message "COM Server registered Ok!".\r
-\r
-See the file COPYING.txt for license information.\r
-\r
-\r
-VideoLAN / VLC\r
----------------\r
-\r
-In order to use this Programm with the VLC-Media-Player properly copy the "AtmoCtrlLib.dll" into the same Location where the vlc.exe is. E.G.: "D:\Programme\VLC". \r
-\r
-NEWER Versions of VideoLAN 1.1.x and higher, don't need a own copy of the "AtmoCtrlLib.dll" in the vlc.exe folder,\r
-if the complete filename of the AtmoWin*.exe is given. (Atmo Filter will try to load the DLL from there)\r
-\r
-Then open VLC and navigate to "Extras" / "Settings" or Press "Ctrl" + "p".\r
-Check that the radiobutton in the lower part of the dialogbox called "Show settings" -> "all" is checked.\r
-Now open the Register "Video" and click on "Filter". There you have to select the checkbox "AtmoLight-Filter".\r
-Afterwards you expand the Tree "Filter" in the Listbox on the left side. By selecting the entry "AtmoLight" you gain more settings.\r
-The most important are right these one at the beginning:\r
-\r
-VideoLAN 1.0.x \r
-==============\r
-"Use build in AtmoLight driver": \r
-Using this Property means VLC will control the Hardware with its built in driver. \r
-(no need for the extra AtmoWin software driver) \r
-\r
-VideoLAN 1.1.x \r
-==============\r
-You have the following choices for "Devicetype" instead of the old settings\r
-"AtmoWin Software" - is only available on Windows and works like the old way useing the external AtmoWin*.exe Software package, with the AtmoCtrlLib.dll.\r
-"Classic AtmoLight" - is the same as the former "use build in AtmoLight driver" \r
-"Quattro AtmoLight" - allows to use up to four serial connected class AtmoLight devices, as one logical device\r
-"DMX" - allows to control a simple serial DMX devices for AtmoLight effects\r
-"MoMoLight" - is a another kind of hardware supporting 2 oder 3 channels.\r
-(see bottom of this file - for more infos about the devices.)\r
-\r
-VideonLAN 1.0.x\r
-===============\r
-"Serial Device / Port":\r
-The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using the Property \r
-"use build in AtmoLight driver" )\r
-\r
-VideonLAN 1.1.x\r
-===============\r
-"Serial Device / Port":\r
-The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using a device\r
-other than "AtmoWin Software") \r
-in the case of the device "Quattro AtmoLight" you may specify up to four ports/devices seperated by\r
-, or ; for example if you are useing two physical devices write\r
-COM6;COM7 or on linux /dev/ttyUSB1;/dev/ttyUSB2\r
-\r
-VideoLAN 1.0.x\r
-==============\r
-"Filename of AtmoWinA.exe":\r
-The Path and the Name of the executable. E.G.:\r
-'D:\atmoWin_0.45\AtmoWinA.exe' (Using this setting expects that you have copied "AtmoCtrlLib.dll" to the Path where VLC.exe is like described before)\r
-\r
-VideoLAN 1.1.x\r
-==============\r
-"Filename of AtmoWinA.exe":\r
-The Path and the Name of the executable. E.G.:\r
-'D:\atmoWin_0.45\AtmoWinA.exe' \r
-in the same path where the .exe resides the "AtmoCtrlLib.dll" should be there. or you may need to place\r
-a copy of this ".dll" into the vlc.exe folder - like in VideoLAN 1.0.x\r
-\r
-Afterwards you should apply those settings by pressing the button "Save".\r
-\r
-\r
-\r
-\r
-VideoLAN 1.1.x - new options and settings\r
-=========================================\r
-Zone Layout for the build-in Atmo\r
-=================================\r
-This is the most important change I think - because the number of analyzed zones isn't\r
-longer fixed to 4 or 5 - it allows to define the physical layout of your lights arround\r
-the screen.\r
-"Number of zones on top"     -- how many light sources are place on top of the screen\r
-                               (number of columns in which the screen should be tiled)\r
-\r
-"Number of zones on bottom"  -- how many light sources are place on bottom of the screen\r
-                               (number of columns in which the screen should be tiled)\r
-\r
-"Zones on left / right side" -- how many light sources are place on right/left of the screen\r
-                               (number of rows in which the screen should be tiled)\r
-                               its assumed that the number on right and left is equal.\r
-\r
-"[] Calculate a average zone" -- define a color pair depending on the complete screen content\r
-\r
-This settings tiles the screen into a number of zones - which get analyzed by atmoLight to\r
-determine a most used color for these areas - each zone has a number starting from zero.\r
-The zones are usualy numbered in clock-wise order starting at the top/left of the screen.\r
-\r
-Example 1: classic Atmo with 4 channels\r
----------------------------------------\r
-"Number of zones on top" = 1\r
-"Number of zones on bottom" = 1\r
-"Zones on left / right side" = 1\r
-"[] Calculate a average zone" = false/0 not checked.\r
-\r
-will produce this zone layout\r
-     ----------- \r
-     | Zone 0  | \r
----------------------\r
-|   |           |   |  \r
-| Z |           | Z | \r
-| o |           | o |\r
-| n |           | n |\r
-| e |           | e |  \r
-|   |           |   | \r
-| 3 |           | 1 |   \r
----------------- ----\r
-     | Zone 2  |\r
-     -----------\r
-\r
-\r
-Example 2: classic Atmo with 4 channels\r
----------------------------------------\r
-"Number of zones on top" = 2\r
-"Number of zones on bottom" = 0\r
-"Zones on left / right side" = 1\r
-"[] Calculate a average zone" = false/0 not checked.\r
-\r
-     ----------- -----------\r
-     | Zone 0  | | Zone 1  |\r
----------------------------------\r
-|   |                       |   |  \r
-| Z |                       | Z | \r
-| o |                       | o |\r
-| n |                       | n |\r
-| e |                       | e |  \r
-|   |                       |   | \r
-| 3 |                       | 2 |   \r
------                       -----\r
-\r
-Example 3: classic Atmo with 4 channels\r
----------------------------------------\r
-"Number of zones on top" = 1\r
-"Number of zones on bottom" = 0\r
-"Zones on left / right side" = 1\r
-"[X] Calculate a average zone" = true/1 checked.\r
\r
-     ----------- \r
-     | Zone 0  | \r
----------------------\r
-|   | --------  |   |  \r
-| Z | |  Z    | | Z | \r
-| o | |  o    | | o |\r
-| n | |  n    | | n |\r
-| e | |  e    | | e |  \r
-|   | |  3    | |   | \r
-| 2 | --------  | 1 |   \r
------           -----\r
-Zone 3 - usualy calcuates the most used color of the full screen / picture / frame\r
-not only at the border of the picture.\r
-\r
-"The average zone" is allways the last in the sequence of numbers.\r
-\r
-\r
-     \r
-the weightning gradients for these zones are auto calculated\r
-from 100% .. 0% starting from the edge.\r
-\r
-thats also the cause why the parameters  Channel assignment changed,\r
-the classic comboboxes are still there for devices with 4 channels ot less,\r
-but for newer devices the "Channel / Zone assignment" should be used which\r
-is defined by a , or ; separated list of "AtmoLight channel numbers" if you\r
-want to hide a calcuated zone from output - you can assign channel -1 to\r
-do this. \r
-for classic AtmoLight with "Example 1" you may write this:\r
--1;3;2;1;0 \r
-AtmoLight Channel 0: gets no zone assigned (-1)\r
-AtmoLight Channel 1: gets zone 3 (left)\r
-AtmoLight Channel 2: gets zone 2 (bottom)\r
-AtmoLight Channel 3: gets zone 1 (right)\r
-AtmoLight Channel 4: gets zone 0 (top)\r
-\r
-\r
-Also the settings for Gradient images change for the new devices, its no longer\r
-sufficient to speficy only 5 image name - because the number of zones is no longer\r
-fixed to five.\r
-So its prefered to set a path ("Gradient Bitmap searchpath"), where files \r
-like "zone_0.bmp" "zone_1.bmp" etc. exists. (with the same rules as defined for \r
-the old zone bitmaps.)\r
---> I think in most cases its no longer required to use this option,\r
-to change the zone layout - for most cases its sufficient to change \r
-"Zone Layout for the build-in Atmo" to get the same effect?\r
-\r
-Live Set of parameters for Buildin AtmoLight\r
-============================================\r
-durring playback with the buildin driver you can now change some settings\r
-of the filter without stopping / starting your movie - just open the\r
-"extras" --> "Effects and Filters"  --> [Video effects] --> [AtmoLight]\r
-- move the sliders or change the calcuation mode, or enable/disable\r
-the debug grid - just in time.\r
-\r
-\r
-new Debugging Option\r
-====================\r
-[] Mark analyzed pixels - puts a grid of the used pixels on each frame\r
-to see from which locations/positions the colors are extracted.\r
-\r
-DMX Options\r
------------\r
-like the group says only for the DMX device\r
-"Count of AtmoLight Channels" - defines how many RGB Channels should be simulated\r
-with this DMX device (each RGB channel needs three DMX channels!)\r
-\r
-"DMX adress for each channel" - defines the DMX Startadress for each AtmoLight\r
-channel as "," or ";" separated list. (starting with 0 up to 252) it is assumed\r
-that the f.e. of the DMX-AtmoLight channel starts at DMX-Channel 5 - that\r
-DMX-Channel 5: is red\r
-DMX-Channel 6: is green\r
-DMX-Channel 7: is blue!\r
-\r
-MoMoLight options\r
------------------\r
-"Count of channels" - defines the devicetype and serial protocol \r
-3: - means 3 channels hardware\r
-4: - means 4 channels hardware\r
-(its required to set the correct number of channels to get this device working,\r
- because the serial protocol isn't the same!)\r
-\r
-\r
-\r
-VideoLan Options and Devices - the buildin version of AtmoLight supports a subset of the\r
-devices that AtmoWin supports.\r
-\r
-- AtmoWin Software - means do not use the VLC buildin video processing - just forward\r
-  the basic preprocessed data to the launched AtmoWinA.exe controlling your hardware.\r
-\r
-- Classic AtmoLight - means the classic hardware from www.vdr-portal.de - with up to 5 channels. \r
-\r
-- Quattro AtmoLight - is nothing else as that you have connected up to 4 "classic AtmoLight" devices\r
-  to your computer creating a up 16 channel Atmo Light - each devices needs its own serial port.\r
-  you have to write the ports seperated by , or ; to [Serial Port/device] f.e. COM3,COM4,COM5 or on \r
-  Linux /dev/ttyUSB01,/dev/ttyUSB02,/dev/ttyUSB03\r
-\r
-- DMX - stands for a simple DMX controller which can control up to 255 DMX devices (lights)\r
-  - f.e. you may have a look here: \r
-     * http://www.dzionsko.de/elektronic/index.htm\r
-     * http://www.ulrichradig.de/ (search for dmx on his page)\r
\r
-- MoMoLight - is a serial device, with 3 or 4 channels - doing nearly the same like\r
-  Classic AtmoLight - just another protocol to control the hardware.\r
-   http://lx.divxstation.com/article.asp?aId=151\r
-   http://www.the-boss.dk/pages/momolight.htm\r
-\r
-\r
-\r
-\r
-\r
-Original Readme - of the Linux Version - from where some code was used\r
-to do the color calculations ...\r
-\r
-######################################################################\r
-Original Readme and Authors of the Linux VDR Plugin!\r
-######################################################################\r
-\r
-Written by:                  Eike Edener   <vdr@edener.de>\r
-Project's homepage:          www.edener.de\r
-Latest version available at: www.edener.de\r
-See the file COPYING for license information.\r
-----------------------------------------------------------------------\r
-\r
-for detailed informations visit the VDR-Wiki:\r
-http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin\r
-\r
-Development:\r
-http://www.vdr-portal.de/board/thread.php?threadid=48574\r
-\r
-Known bugs:\r
-n/a\r
-\r
-----------------------------------------------------------------------\r
+This piece of software is based on the software and descriptions mentioned below -
+
+
+(re)Written by:              Igor / Atmo (aka André Weber)  - WeberAndre@gmx.de
+                             Matthiaz
+                             MacGyver2k
+
+if you need to contact one of us - come to www.vdr-portal.de
+
+http://www.vdr-portal.de/board/thread.php?threadid=59294 -- Description and Development of the Windows Software
+http://www.vdr-portal.de/board/thread.php?threadid=48574 -- Description and Development of the Hardware part
+
+=====================================================
+Info for Users on Vista or Windows 7 with active UAC!
+=====================================================
+for the first launch do it as Administrator with the following command line
+
+AtmoWinA.exe /register
+
+to create the required registry entries for the COM Objects, without
+these registry entries - the DirectShow Filter and also the VLC Plugin
+will not work.
+If anything went fine you should see the message "COM Server registered Ok!".
+
+See the file COPYING.txt for license information.
+
+
+VideoLAN / VLC
+---------------
+
+In order to use this Programm with the VLC-Media-Player properly copy the "AtmoCtrlLib.dll" into the same Location where the vlc.exe is. E.G.: "D:\Programme\VLC".
+
+NEWER Versions of VideoLAN 1.1.x and higher, don't need a own copy of the "AtmoCtrlLib.dll" in the vlc.exe folder,
+if the complete filename of the AtmoWin*.exe is given. (Atmo Filter will try to load the DLL from there)
+
+Then open VLC and navigate to "Extras" / "Settings" or Press "Ctrl" + "p".
+Check that the radiobutton in the lower part of the dialogbox called "Show settings" -> "all" is checked.
+Now open the Register "Video" and click on "Filter". There you have to select the checkbox "AtmoLight-Filter".
+Afterwards you expand the Tree "Filter" in the Listbox on the left side. By selecting the entry "AtmoLight" you gain more settings.
+The most important are right these one at the beginning:
+
+VideoLAN 1.0.x
+==============
+"Use build in AtmoLight driver":
+Using this Property means VLC will control the Hardware with its built in driver.
+(no need for the extra AtmoWin software driver)
+
+VideoLAN 1.1.x
+==============
+You have the following choices for "Devicetype" instead of the old settings
+"AtmoWin Software" - is only available on Windows and works like the old way useing the external AtmoWin*.exe Software package, with the AtmoCtrlLib.dll.
+"Classic AtmoLight" - is the same as the former "use build in AtmoLight driver"
+"Quattro AtmoLight" - allows to use up to four serial connected class AtmoLight devices, as one logical device
+"DMX" - allows to control a simple serial DMX devices for AtmoLight effects
+"MoMoLight" - is a another kind of hardware supporting 2 oder 3 channels.
+(see bottom of this file - for more infos about the devices.)
+
+VideonLAN 1.0.x
+===============
+"Serial Device / Port":
+The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using the Property
+"use build in AtmoLight driver" )
+
+VideonLAN 1.1.x
+===============
+"Serial Device / Port":
+The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using a device
+other than "AtmoWin Software")
+in the case of the device "Quattro AtmoLight" you may specify up to four ports/devices seperated by
+, or ; for example if you are useing two physical devices write
+COM6;COM7 or on linux /dev/ttyUSB1;/dev/ttyUSB2
+
+VideoLAN 1.0.x
+==============
+"Filename of AtmoWinA.exe":
+The Path and the Name of the executable. E.G.:
+'D:\atmoWin_0.45\AtmoWinA.exe' (Using this setting expects that you have copied "AtmoCtrlLib.dll" to the Path where VLC.exe is like described before)
+
+VideoLAN 1.1.x
+==============
+"Filename of AtmoWinA.exe":
+The Path and the Name of the executable. E.G.:
+'D:\atmoWin_0.45\AtmoWinA.exe'
+in the same path where the .exe resides the "AtmoCtrlLib.dll" should be there. or you may need to place
+a copy of this ".dll" into the vlc.exe folder - like in VideoLAN 1.0.x
+
+Afterwards you should apply those settings by pressing the button "Save".
+
+
+
+
+VideoLAN 1.1.x - new options and settings
+=========================================
+Zone Layout for the build-in Atmo
+=================================
+This is the most important change I think - because the number of analyzed zones isn't
+longer fixed to 4 or 5 - it allows to define the physical layout of your lights arround
+the screen.
+"Number of zones on top"     -- how many light sources are place on top of the screen
+                               (number of columns in which the screen should be tiled)
+
+"Number of zones on bottom"  -- how many light sources are place on bottom of the screen
+                               (number of columns in which the screen should be tiled)
+
+"Zones on left / right side" -- how many light sources are place on right/left of the screen
+                               (number of rows in which the screen should be tiled)
+                               its assumed that the number on right and left is equal.
+
+"[] Calculate a average zone" -- define a color pair depending on the complete screen content
+
+This settings tiles the screen into a number of zones - which get analyzed by atmoLight to
+determine a most used color for these areas - each zone has a number starting from zero.
+The zones are usualy numbered in clock-wise order starting at the top/left of the screen.
+
+Example 1: classic Atmo with 4 channels
+---------------------------------------
+"Number of zones on top" = 1
+"Number of zones on bottom" = 1
+"Zones on left / right side" = 1
+"[] Calculate a average zone" = false/0 not checked.
+
+will produce this zone layout
+     -----------
+     | Zone 0  |
+---------------------
+|   |           |   |
+| Z |           | Z |
+| o |           | o |
+| n |           | n |
+| e |           | e |
+|   |           |   |
+| 3 |           | 1 |
+---------------- ----
+     | Zone 2  |
+     -----------
+
+
+Example 2: classic Atmo with 4 channels
+---------------------------------------
+"Number of zones on top" = 2
+"Number of zones on bottom" = 0
+"Zones on left / right side" = 1
+"[] Calculate a average zone" = false/0 not checked.
+
+     ----------- -----------
+     | Zone 0  | | Zone 1  |
+---------------------------------
+|   |                       |   |
+| Z |                       | Z |
+| o |                       | o |
+| n |                       | n |
+| e |                       | e |
+|   |                       |   |
+| 3 |                       | 2 |
+-----                       -----
+
+Example 3: classic Atmo with 4 channels
+---------------------------------------
+"Number of zones on top" = 1
+"Number of zones on bottom" = 0
+"Zones on left / right side" = 1
+"[X] Calculate a average zone" = true/1 checked.
+
+     -----------
+     | Zone 0  |
+---------------------
+|   | --------  |   |
+| Z | |  Z    | | Z |
+| o | |  o    | | o |
+| n | |  n    | | n |
+| e | |  e    | | e |
+|   | |  3    | |   |
+| 2 | --------  | 1 |
+-----           -----
+Zone 3 - usualy calcuates the most used color of the full screen / picture / frame
+not only at the border of the picture.
+
+"The average zone" is allways the last in the sequence of numbers.
+
+
+
+the weightning gradients for these zones are auto calculated
+from 100% .. 0% starting from the edge.
+
+thats also the cause why the parameters  Channel assignment changed,
+the classic comboboxes are still there for devices with 4 channels ot less,
+but for newer devices the "Channel / Zone assignment" should be used which
+is defined by a , or ; separated list of "AtmoLight channel numbers" if you
+want to hide a calcuated zone from output - you can assign channel -1 to
+do this.
+for classic AtmoLight with "Example 1" you may write this:
+-1;3;2;1;0
+AtmoLight Channel 0: gets no zone assigned (-1)
+AtmoLight Channel 1: gets zone 3 (left)
+AtmoLight Channel 2: gets zone 2 (bottom)
+AtmoLight Channel 3: gets zone 1 (right)
+AtmoLight Channel 4: gets zone 0 (top)
+
+
+Also the settings for Gradient images change for the new devices, its no longer
+sufficient to speficy only 5 image name - because the number of zones is no longer
+fixed to five.
+So its prefered to set a path ("Gradient Bitmap searchpath"), where files
+like "zone_0.bmp" "zone_1.bmp" etc. exists. (with the same rules as defined for
+the old zone bitmaps.)
+--> I think in most cases its no longer required to use this option,
+to change the zone layout - for most cases its sufficient to change
+"Zone Layout for the build-in Atmo" to get the same effect?
+
+Live Set of parameters for Buildin AtmoLight
+============================================
+durring playback with the buildin driver you can now change some settings
+of the filter without stopping / starting your movie - just open the
+"extras" --> "Effects and Filters"  --> [Video effects] --> [AtmoLight]
+- move the sliders or change the calcuation mode, or enable/disable
+the debug grid - just in time.
+
+
+new Debugging Option
+====================
+[] Mark analyzed pixels - puts a grid of the used pixels on each frame
+to see from which locations/positions the colors are extracted.
+
+DMX Options
+-----------
+like the group says only for the DMX device
+"Count of AtmoLight Channels" - defines how many RGB Channels should be simulated
+with this DMX device (each RGB channel needs three DMX channels!)
+
+"DMX adress for each channel" - defines the DMX Startadress for each AtmoLight
+channel as "," or ";" separated list. (starting with 0 up to 252) it is assumed
+that the f.e. of the DMX-AtmoLight channel starts at DMX-Channel 5 - that
+DMX-Channel 5: is red
+DMX-Channel 6: is green
+DMX-Channel 7: is blue!
+
+MoMoLight options
+-----------------
+"Count of channels" - defines the devicetype and serial protocol
+3: - means 3 channels hardware
+4: - means 4 channels hardware
+(its required to set the correct number of channels to get this device working,
+ because the serial protocol isn't the same!)
+
+
+
+VideoLan Options and Devices - the buildin version of AtmoLight supports a subset of the
+devices that AtmoWin supports.
+
+- AtmoWin Software - means do not use the VLC buildin video processing - just forward
+  the basic preprocessed data to the launched AtmoWinA.exe controlling your hardware.
+
+- Classic AtmoLight - means the classic hardware from www.vdr-portal.de - with up to 5 channels.
+
+- Quattro AtmoLight - is nothing else as that you have connected up to 4 "classic AtmoLight" devices
+  to your computer creating a up 16 channel Atmo Light - each devices needs its own serial port.
+  you have to write the ports seperated by , or ; to [Serial Port/device] f.e. COM3,COM4,COM5 or on
+  Linux /dev/ttyUSB01,/dev/ttyUSB02,/dev/ttyUSB03
+
+- DMX - stands for a simple DMX controller which can control up to 255 DMX devices (lights)
+  - f.e. you may have a look here:
+     * http://www.dzionsko.de/elektronic/index.htm
+     * http://www.ulrichradig.de/ (search for dmx on his page)
+
+- MoMoLight - is a serial device, with 3 or 4 channels - doing nearly the same like
+  Classic AtmoLight - just another protocol to control the hardware.
+   http://lx.divxstation.com/article.asp?aId=151
+   http://www.the-boss.dk/pages/momolight.htm
+
+- Fnordlicht - is a serial device with up to four channels
+   http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
+   http://github.com/fd0/fnordlicht/
+
+
+
+
+Original Readme - of the Linux Version - from where some code was used
+to do the color calculations ...
+
+######################################################################
+Original Readme and Authors of the Linux VDR Plugin!
+######################################################################
+
+Written by:                  Eike Edener   <vdr@edener.de>
+Project's homepage:          www.edener.de
+Latest version available at: www.edener.de
+See the file COPYING for license information.
+----------------------------------------------------------------------
+
+for detailed informations visit the VDR-Wiki:
+http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin
+
+Development:
+http://www.vdr-portal.de/board/thread.php?threadid=48574
+
+Known bugs:
+n/a
+
+----------------------------------------------------------------------
index addb87c8e6a23ebe3b983bc7dd4c736cac19f864..0bdc46798383ef1ba62a7b812a4b7892d8f41dba 100644 (file)
@@ -139,7 +139,8 @@ static const int pi_device_type_values[] = {
      1, /* AtmoLight classic */
      2, /* Quattro AtmoLight */
      3, /* DMX Device */
-     4  /* MoMoLight device */
+     4, /* MoMoLight device */
+        5  /* fnordlicht */
 };
 static const char *const ppsz_device_type_descriptions[] = {
 #if defined( WIN32 )
@@ -148,7 +149,8 @@ static const char *const ppsz_device_type_descriptions[] = {
         N_("Classic AtmoLight"),
         N_("Quattro AtmoLight"),
         N_("DMX"),
-        N_("MoMoLight")
+        N_("MoMoLight"),
+        N_("fnordlicht")
 };
 
 #define DMX_CHANNELS_TEXT      N_("Count of AtmoLight channels")
@@ -162,6 +164,11 @@ static const char *const ppsz_device_type_descriptions[] = {
 #define MOMO_CHANNELS_LONGTEXT  N_("Depending on your MoMoLight hardware " \
                                    "choose 3 or 4 channels")
 
+#define FNORDLICHT_AMOUNT_TEXT      N_("Count of fnordlicht's")
+#define FNORDLICHT_AMOUNT_LONGTEXT  N_("Depending on the amount your " \
+                                   "fnordlicht hardware " \
+                                   "choose 1 to 4 channels")
+
 #if defined( WIN32 )
 #  define DEFAULT_DEVICE   0
 #else
@@ -376,7 +383,7 @@ add_string(CFG_PREFIX "serialdev", "COM1", NULL,
 add_file(CFG_PREFIX "atmowinexe", NULL, NULL,
          ATMOWINEXE_TEXT, ATMOWINEXE_LONGTEXT, false )
 #else
-add_string(CFG_PREFIX "serialdev", "/dev/ttyS01", NULL,
+add_string(CFG_PREFIX "serialdev", "/dev/ttyUSB0", NULL,
            SERIALDEV_TEXT, SERIALDEV_LONGTEXT, false )
 #endif
 
@@ -421,6 +428,13 @@ set_section( N_("MoMoLight options" ), 0 )
 add_integer_with_range(CFG_PREFIX "momo-channels",   3, 3, 4, NULL,
                        MOMO_CHANNELS_TEXT, MOMO_CHANNELS_LONGTEXT, false)
 
+/* 2,2,4 means 2 is the default value, 1 minimum amount,
+   4 maximum amount
+*/
+set_section( N_("fnordlicht options" ), 0 )
+add_integer_with_range(CFG_PREFIX "fnordlicht-amount",   2, 1, 4, NULL,
+                       FNORDLICHT_AMOUNT_TEXT,
+                       FNORDLICHT_AMOUNT_LONGTEXT, false)
 
 
 /*
@@ -652,6 +666,7 @@ static const char *const ppsz_filter_options[] = {
         "dmx-channels",
         "dmx-chbase",
         "momo-channels",
+        "fnordlicht-amount",
 
 #if defined(WIN32 )
         "atmowinexe",
@@ -1523,6 +1538,14 @@ static void Atmo_SetupConfig(filter_t *p_filter, CAtmoConfig *p_atmo_config)
     p_atmo_config->setMoMo_Channels(
         var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "momo-channels")
        );
+
+    /*
+      fnordlicht options
+    */
+    p_atmo_config->setFnordlicht_Amount(
+        var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "fnordlicht-amount")
+       );
+
 }
 
 
@@ -1603,48 +1626,58 @@ static void Atmo_SetupParameters(filter_t *p_filter)
 
             /* importing all required functions I hope*/
             p_sys->pf_ctrl_atmo_initialize =
-                (int32_t (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoInitialize");
+                (int32_t (*)(void))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                   "AtmoInitialize");
             if(!p_sys->pf_ctrl_atmo_initialize)
                 msg_Err( p_filter, "export AtmoInitialize missing.");
 
             p_sys->pf_ctrl_atmo_finalize =
-                (void (*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoFinalize");
+                (void (*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                              "AtmoFinalize");
             if(!p_sys->pf_ctrl_atmo_finalize)
                 msg_Err( p_filter, "export AtmoFinalize missing.");
 
             p_sys->pf_ctrl_atmo_switch_effect =
-                (int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSwitchEffect");
+                (int32_t(*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                                "AtmoSwitchEffect" );
             if(!p_sys->pf_ctrl_atmo_switch_effect)
                 msg_Err( p_filter, "export AtmoSwitchEffect missing.");
 
             p_sys->pf_ctrl_atmo_set_live_source =
-                (int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSetLiveSource");
+                (int32_t(*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                                "AtmoSetLiveSource" );
             if(!p_sys->pf_ctrl_atmo_set_live_source)
                 msg_Err( p_filter, "export AtmoSetLiveSource missing.");
 
             p_sys->pf_ctrl_atmo_create_transfer_buffers =
-                (void (*)(int32_t, int32_t, int32_t , int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoCreateTransferBuffers");
+                (void (*)(int32_t, int32_t, int32_t , int32_t))
+                                       GetProcAddress( p_sys->h_AtmoCtrl,
+                                    "AtmoCreateTransferBuffers" );
             if(!p_sys->pf_ctrl_atmo_create_transfer_buffers)
                 msg_Err( p_filter, "export AtmoCreateTransferBuffers missing.");
 
             p_sys->pf_ctrl_atmo_lock_transfer_buffer=
-                (uint8_t*(*) (void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoLockTransferBuffer");
+                (uint8_t*(*) (void))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                               "AtmoLockTransferBuffer");
             if(!p_sys->pf_ctrl_atmo_lock_transfer_buffer)
                 msg_Err( p_filter, "export AtmoLockTransferBuffer missing.");
 
             p_sys->pf_ctrl_atmo_send_pixel_data =
-                (void (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSendPixelData");
+                (void (*)(void))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                           "AtmoSendPixelData");
             if(!p_sys->pf_ctrl_atmo_send_pixel_data)
                 msg_Err( p_filter, "export AtmoSendPixelData missing.");
 
             p_sys->pf_ctrl_atmo_get_image_size =
-                (void (*)(int32_t*,int32_t*))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoWinGetImageSize");
+                (void (*)(int32_t*,int32_t*))GetProcAddress( p_sys->h_AtmoCtrl,
+                                                                            "AtmoWinGetImageSize");
             if(!p_sys->pf_ctrl_atmo_get_image_size)
                 msg_Err( p_filter, "export AtmoWinGetImageSize missing.");
 
         } else {
             /* the DLL is missing try internal filter ...*/
-            msg_Warn( p_filter, "AtmoCtrlLib.dll missing fallback to internal atmo classic driver");
+            msg_Warn( p_filter,
+                               "AtmoCtrlLib.dll missing fallback to internal atmo classic driver" );
             p_sys->i_device_type = 1;
         }
     }
@@ -1684,6 +1717,10 @@ static void Atmo_SetupParameters(filter_t *p_filter)
                 p_sys->p_atmo_config->setConnectionType( actMoMoLight );
                 break;
 
+            case 5:
+                p_sys->p_atmo_config->setConnectionType( actFnordlicht );
+                break;
+
             default:
                 msg_Warn( p_filter, "invalid device type %d found",
                                     p_sys->i_device_type );
@@ -2227,7 +2264,8 @@ static void CreateMiniImage( filter_t *p_filter, picture_t *p_inpic)
         }
     }
 
-    msg_Dbg( p_filter, "AtmoFrame %u Time: %d ms", p_sys->ui_frame_counter, mdate() / 1000);
+    msg_Dbg( p_filter, "AtmoFrame %u Time: %d ms", p_sys->ui_frame_counter,
+                               mdate() / 1000);
     p_sys->ui_frame_counter++;
 #endif
 
@@ -2532,7 +2570,7 @@ static int AtmoSettingsCallback( vlc_object_t *p_this, char const *psz_var,
        );
 
         if( !strcmp( psz_var, CFG_PREFIX "filtermode" ))
-            p_atmo_config->setLiveViewFilterMode( (AtmoFilterMode)newval.i_int);
+            p_atmo_config->setLiveViewFilterMode( (AtmoFilterMode)newval.i_int );
 
         else if( !strcmp( psz_var, CFG_PREFIX "percentnew" ))
                  p_atmo_config->setLiveViewFilter_PercentNew( newval.i_int );
@@ -2762,10 +2800,14 @@ static void atmo_parse_crop(char *psz_cropconfig,
             i_crop_bottom = strtol( psz_end, &psz_end, 10 );
             if( *psz_end != '\0' ) return;
 
-            i_width = fmt_render.i_visible_width - i_crop_left - i_crop_right;
+            i_width = fmt_render.i_visible_width -
+                                               i_crop_left -
+                                               i_crop_right;
             i_visible_width = i_width;
 
-            i_height = fmt_render.i_visible_height - i_crop_top - i_crop_bottom;
+            i_height = fmt_render.i_visible_height -
+                                               i_crop_top -
+                                               i_crop_bottom;
             i_visible_height = i_height;
 
             i_x_offset = i_crop_left;