2 * AtmoTools.cpp: Collection of tool and helperfunction
4 * See the README.txt file for copyright information and how to reach the author(s).
10 #include "AtmoDynData.h"
11 #include "AtmoLiveView.h"
12 #include "AtmoClassicConnection.h"
13 #include "AtmoDmxSerialConnection.h"
14 #include "AtmoMultiConnection.h"
15 #include "MoMoConnection.h"
16 #include "FnordlichtConnection.h"
17 #include "AtmoExternalCaptureInput.h"
20 #if !defined(_ATMO_VLC_PLUGIN_)
21 # include "AtmoColorChanger.h"
22 # include "AtmoLeftRightColorChanger.h"
24 # include "AtmoDummyConnection.h"
25 # include "AtmoNulConnection.h"
26 # include "MondolightConnection.h"
28 # include "AtmoGdiDisplayCaptureInput.h"
31 CAtmoTools::CAtmoTools(void)
35 CAtmoTools::~CAtmoTools(void)
39 void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
41 pDynData->LockCriticalSection();
43 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
44 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
45 if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) {
48 AllocColorPacket(packet, atmoConfig->getZoneCount());
50 // set a special color? on shutdown of the software? mostly may use black or so ...
51 // if this function ist disabled ... atmo will continuing to show the last color...
52 for(i = 0; i < packet->numColors; i++) {
53 packet->zone[i].r = atmoConfig->getShutdownColor_Red();
54 packet->zone[i].g = atmoConfig->getShutdownColor_Green();
55 packet->zone[i].b = atmoConfig->getShutdownColor_Blue();
58 packet = CAtmoTools::ApplyGamma(atmoConfig, packet);
60 if(atmoConfig->isUseSoftwareWhiteAdj())
61 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
63 atmoConnection->SendData(packet);
65 delete (char *)packet;
69 pDynData->UnLockCriticalSection();
72 EffectMode CAtmoTools::SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode)
74 // may need a critical section??
75 if(pDynData == NULL) {
78 pDynData->LockCriticalSection();
80 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
81 if(atmoConfig == NULL) {
82 pDynData->UnLockCriticalSection();
85 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
87 EffectMode oldEffectMode = atmoConfig->getEffectMode();
88 CThread *currentEffect = pDynData->getEffectThread();
89 CAtmoInput *currentInput = pDynData->getLiveInput();
90 CAtmoPacketQueue *currentPacketQueue = pDynData->getLivePacketQueue();
93 if(oldEffectMode == emLivePicture) {
94 /* in case of disabling the live mode
95 first we have to stop the input
96 then the effect thread!
98 if(currentInput != NULL) {
99 pDynData->setLiveInput( NULL );
100 currentInput->Close();
106 // stop and delete/cleanup current Effect Thread...
107 pDynData->setEffectThread( NULL );
108 if(currentEffect != NULL) {
109 currentEffect->Terminate();
110 delete currentEffect;
111 currentEffect = NULL;
114 if(oldEffectMode == emLivePicture) {
116 and last we kill the PacketQueue used for communication between the threads
118 pDynData->setLivePacketQueue( NULL );
119 delete currentPacketQueue;
120 currentPacketQueue = NULL;
123 if((atmoConnection!=NULL) && (atmoConnection->isOpen()==ATMO_TRUE)) {
124 // neuen EffectThread nur mit aktiver Connection starten...
126 switch(newEffectMode) {
130 case emStaticColor: {
131 // get values from config - and put them to all channels?
133 AllocColorPacket(packet, atmoConfig->getZoneCount());
134 for(int i=0; i < packet->numColors; i++){
135 packet->zone[i].r = atmoConfig->getStaticColor_Red();
136 packet->zone[i].g = atmoConfig->getStaticColor_Green();
137 packet->zone[i].b = atmoConfig->getStaticColor_Blue();
140 packet = CAtmoTools::ApplyGamma( atmoConfig, packet );
142 if(atmoConfig->isUseSoftwareWhiteAdj())
143 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
145 atmoConnection->SendData( packet );
147 delete (char *)packet;
152 case emLivePicture: {
153 currentEffect = new CAtmoLiveView(pDynData);
155 #if !defined(_ATMO_VLC_PLUGIN_)
156 CAtmoPacketQueueStatus *packetMon = NULL;
157 if(atmoConfig->getShow_statistics()) {
158 packetMon = new CAtmoPacketQueueStatus(pDynData->getHinstance(), (HWND)NULL);
159 packetMon->createWindow();
160 packetMon->showWindow(SW_SHOW);
162 currentPacketQueue = new CAtmoPacketQueue(packetMon);
163 pDynData->setLivePictureSource(lpsScreenCapture);
164 currentInput = new CAtmoGdiDisplayCaptureInput( pDynData );
166 currentPacketQueue = new CAtmoPacketQueue();
167 pDynData->setLivePictureSource(lpsExtern);
168 currentInput = new CAtmoExternalCaptureInput( pDynData );
173 #if !defined(_ATMO_VLC_PLUGIN_)
175 currentEffect = new CAtmoColorChanger(atmoConnection, atmoConfig);
178 case emLrColorChange:
179 currentEffect = new CAtmoLeftRightColorChanger(atmoConnection, atmoConfig);
186 atmoConfig->setEffectMode( newEffectMode );
188 pDynData->setLivePacketQueue( currentPacketQueue );
189 pDynData->setEffectThread( currentEffect );
190 pDynData->setLiveInput( currentInput );
192 if(currentEffect != NULL)
193 currentEffect->Run();
194 if(currentInput != NULL)
195 currentInput->Open();
197 pDynData->UnLockCriticalSection();
198 return oldEffectMode;
201 LivePictureSource CAtmoTools::SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource)
203 LivePictureSource oldSource;
204 pDynData->LockCriticalSection();
206 oldSource = pDynData->getLivePictureSource();
207 pDynData->setLivePictureSource( newLiveSource );
209 if ((pDynData->getAtmoConfig()->getEffectMode() == emLivePicture) &&
210 (pDynData->getEffectThread() != NULL) &&
211 (pDynData->getLivePacketQueue() != NULL))
213 CAtmoInput *input = pDynData->getLiveInput();
214 pDynData->setLiveInput( NULL );
221 switch(pDynData->getLivePictureSource()) {
222 #if !defined(_ATMO_VLC_PLUGIN_)
223 case lpsScreenCapture:
224 input = new CAtmoGdiDisplayCaptureInput( pDynData );
228 input = new CAtmoExternalCaptureInput( pDynData );
232 pDynData->setLiveInput( input );
237 pDynData->UnLockCriticalSection();
241 ATMO_BOOL CAtmoTools::RecreateConnection(CAtmoDynData *pDynData)
243 pDynData->LockCriticalSection();
245 CAtmoConnection *current = pDynData->getAtmoConnection();
246 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
247 AtmoConnectionType act = atmoConfig->getConnectionType();
248 pDynData->setAtmoConnection(NULL);
249 if(current != NULL) {
250 current->CloseConnection();
255 case actClassicAtmo: {
256 CAtmoClassicConnection *tempConnection = new CAtmoClassicConnection( atmoConfig );
257 if(tempConnection->OpenConnection() == ATMO_FALSE) {
258 #if !defined(_ATMO_VLC_PLUGIN_)
259 if(atmoConfig->getIgnoreConnectionErrorOnStartup() == ATMO_FALSE)
261 char errorMsgBuf[200];
262 sprintf(errorMsgBuf,"Failed to open serial port com%d with errorcode: %d (0x%x)",
263 pDynData->getAtmoConfig()->getComport(),
264 tempConnection->getLastError(),
265 tempConnection->getLastError()
267 MessageBox(0,errorMsgBuf,"Error",MB_ICONERROR | MB_OK);
270 pDynData->setAtmoConnection(tempConnection);
272 pDynData->UnLockCriticalSection();
275 pDynData->setAtmoConnection(tempConnection);
276 pDynData->ReloadZoneDefinitionBitmaps();
278 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
280 CAtmoTools::SetChannelAssignment(pDynData,
281 atmoConfig->getCurrentChannelAssignment());
283 pDynData->UnLockCriticalSection();
287 #if !defined(_ATMO_VLC_PLUGIN_)
290 // actDummy8,actDummy12,actDummy16
291 CAtmoDummyConnection *tempConnection = new CAtmoDummyConnection(pDynData->getHinstance(),
293 if(tempConnection->OpenConnection() == ATMO_FALSE) {
294 pDynData->setAtmoConnection(tempConnection);
295 pDynData->UnLockCriticalSection();
298 pDynData->setAtmoConnection(tempConnection);
299 pDynData->ReloadZoneDefinitionBitmaps();
301 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
303 CAtmoTools::SetChannelAssignment(pDynData, pDynData->getAtmoConfig()->getCurrentChannelAssignment());
305 pDynData->UnLockCriticalSection();
311 // create here your DMX connections... instead of the dummy....
312 CAtmoDmxSerialConnection *tempConnection = new CAtmoDmxSerialConnection( atmoConfig );
313 if(tempConnection->OpenConnection() == ATMO_FALSE) {
314 pDynData->setAtmoConnection(tempConnection);
316 pDynData->UnLockCriticalSection();
319 pDynData->setAtmoConnection(tempConnection);
320 pDynData->ReloadZoneDefinitionBitmaps();
322 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
324 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
326 pDynData->UnLockCriticalSection();
330 #if !defined(_ATMO_VLC_PLUGIN_)
332 CAtmoNulConnection *tempConnection = new CAtmoNulConnection( atmoConfig );
333 if(tempConnection->OpenConnection() == ATMO_FALSE) {
334 pDynData->setAtmoConnection(tempConnection);
335 pDynData->UnLockCriticalSection();
338 pDynData->setAtmoConnection(tempConnection);
339 pDynData->ReloadZoneDefinitionBitmaps();
341 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
343 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
345 pDynData->UnLockCriticalSection();
351 CAtmoMultiConnection *tempConnection = new CAtmoMultiConnection( atmoConfig );
352 if(tempConnection->OpenConnection() == ATMO_FALSE) {
353 pDynData->setAtmoConnection(tempConnection);
354 pDynData->UnLockCriticalSection();
357 pDynData->setAtmoConnection(tempConnection);
358 pDynData->ReloadZoneDefinitionBitmaps();
360 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
362 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
364 pDynData->UnLockCriticalSection();
368 #if !defined(_ATMO_VLC_PLUGIN_)
369 case actMondolight: {
370 CMondolightConnection *tempConnection = new CMondolightConnection( atmoConfig );
371 if(tempConnection->OpenConnection() == ATMO_FALSE) {
372 pDynData->setAtmoConnection(tempConnection);
373 pDynData->UnLockCriticalSection();
376 pDynData->setAtmoConnection(tempConnection);
377 pDynData->ReloadZoneDefinitionBitmaps();
379 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
381 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
383 pDynData->UnLockCriticalSection();
388 CMoMoConnection *tempConnection = new CMoMoConnection( atmoConfig );
389 if(tempConnection->OpenConnection() == ATMO_FALSE) {
390 pDynData->setAtmoConnection(tempConnection);
391 pDynData->UnLockCriticalSection();
394 pDynData->setAtmoConnection(tempConnection);
395 pDynData->ReloadZoneDefinitionBitmaps();
397 tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
399 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
401 pDynData->UnLockCriticalSection();
405 case actFnordlicht: {
406 CFnordlichtConnection *tempConnection = new CFnordlichtConnection( atmoConfig );
407 if(tempConnection->OpenConnection() == ATMO_FALSE) {
408 pDynData->setAtmoConnection(tempConnection);
409 pDynData->UnLockCriticalSection();
412 pDynData->setAtmoConnection(tempConnection);
413 pDynData->ReloadZoneDefinitionBitmaps();
415 tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
417 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
419 pDynData->UnLockCriticalSection();
424 pDynData->UnLockCriticalSection();
430 pColorPacket CAtmoTools::WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
432 int w_adj_red = pAtmoConfig->getWhiteAdjustment_Red();
433 int w_adj_green = pAtmoConfig->getWhiteAdjustment_Green();
434 int w_adj_blue = pAtmoConfig->getWhiteAdjustment_Blue();
436 for (int i = 0; i < ColorPacket->numColors; i++) {
437 ColorPacket->zone[i].r = (unsigned char)(((int)w_adj_red * (int)ColorPacket->zone[i].r) / 255);
438 ColorPacket->zone[i].g = (unsigned char)(((int)w_adj_green * (int)ColorPacket->zone[i].g) / 255);
439 ColorPacket->zone[i].b = (unsigned char)(((int)w_adj_blue * (int)ColorPacket->zone[i].b) / 255);
444 pColorPacket CAtmoTools::ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
447 switch(pAtmoConfig->getSoftware_gamma_mode()) {
450 double GammaRed = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_red());
451 double GammaGreen = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_green());
452 double GammaBlue = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_blue());
453 for (int i = 0; i < ColorPacket->numColors; i++)
455 v = ColorPacket->zone[i].r;
456 v = (pow( v / 255.0f, GammaRed ) * 255.0f);
457 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
459 v = ColorPacket->zone[i].g;
460 v = (pow( v / 255.0f, GammaGreen ) * 255.0f);
461 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
463 v = ColorPacket->zone[i].b;
464 v = (pow( v / 255.0f, GammaBlue ) * 255.0f);
465 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
470 double Gamma = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_global());
471 for (int i = 0; i < ColorPacket->numColors; i++)
473 v = ColorPacket->zone[i].r;
474 v = (pow( v / 255.0f, Gamma ) * 255.0f);
475 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
477 v = ColorPacket->zone[i].g;
478 v = (pow( v / 255.0f, Gamma ) * 255.0f);
479 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
481 v = ColorPacket->zone[i].b;
482 v = (pow( v / 255.0f, Gamma ) * 255.0f);
483 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
491 int CAtmoTools::SetChannelAssignment(CAtmoDynData *pDynData, int index)
493 CAtmoConfig *pAtmoConfig = pDynData->getAtmoConfig();
494 CAtmoConnection *pAtmoConnection = pDynData->getAtmoConnection();
495 int oldIndex = pAtmoConfig->getCurrentChannelAssignment();
497 CAtmoChannelAssignment *ca = pAtmoConfig->getChannelAssignment(index);
498 if((ca!=NULL) && (pAtmoConnection!=NULL)) {
499 pAtmoConnection->SetChannelAssignment(ca);
500 pAtmoConfig->setCurrentChannelAssignment(index);
506 #if !defined(_ATMO_VLC_PLUGIN_)
508 void CAtmoTools::SaveBitmap(HDC hdc,HBITMAP hBmp,char *fileName) {
510 BITMAPFILEHEADER bmpFileHeader;
511 ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
512 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
514 GetDIBits(hdc,hBmp,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
515 if(bmpInfo.bmiHeader.biSizeImage<=0)
516 bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth * abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
517 void *pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
518 bmpInfo.bmiHeader.biCompression=BI_RGB;
520 GetDIBits(hdc,hBmp,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
523 bmpFileHeader.bfReserved1=0;
524 bmpFileHeader.bfReserved2=0;
525 bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
526 bmpFileHeader.bfType = MakeIntelWord('M','B');
527 bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
531 fp = fopen(fileName,"wb");
532 fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
533 fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
534 fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);