2 * AtmoTools.cpp: Collection of tool and helperfunction
4 * See the README.txt file for copyright information and how to reach the author(s).
13 #include "AtmoTools.h"
14 #include "AtmoDynData.h"
15 #include "AtmoLiveView.h"
16 #include "AtmoClassicConnection.h"
17 #include "AtmoDmxSerialConnection.h"
18 #include "AtmoMultiConnection.h"
19 #include "MoMoConnection.h"
20 #include "FnordlichtConnection.h"
21 #include "AtmoExternalCaptureInput.h"
24 #if !defined(_ATMO_VLC_PLUGIN_)
25 # include "AtmoColorChanger.h"
26 # include "AtmoLeftRightColorChanger.h"
28 # include "AtmoDummyConnection.h"
29 # include "AtmoNulConnection.h"
30 # include "MondolightConnection.h"
32 # include "AtmoGdiDisplayCaptureInput.h"
35 CAtmoTools::CAtmoTools(void)
39 CAtmoTools::~CAtmoTools(void)
43 void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
45 pDynData->LockCriticalSection();
47 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
48 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
49 if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) {
52 AllocColorPacket(packet, atmoConfig->getZoneCount());
54 // set a special color? on shutdown of the software? mostly may use black or so ...
55 // if this function ist disabled ... atmo will continuing to show the last color...
56 for(i = 0; i < packet->numColors; i++) {
57 packet->zone[i].r = atmoConfig->getShutdownColor_Red();
58 packet->zone[i].g = atmoConfig->getShutdownColor_Green();
59 packet->zone[i].b = atmoConfig->getShutdownColor_Blue();
62 packet = CAtmoTools::ApplyGamma(atmoConfig, packet);
64 if(atmoConfig->isUseSoftwareWhiteAdj())
65 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
67 atmoConnection->SendData(packet);
73 pDynData->UnLockCriticalSection();
76 EffectMode CAtmoTools::SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode)
78 // may need a critical section??
79 if(pDynData == NULL) {
82 pDynData->LockCriticalSection();
84 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
85 if(atmoConfig == NULL) {
86 pDynData->UnLockCriticalSection();
89 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
91 EffectMode oldEffectMode = atmoConfig->getEffectMode();
92 CThread *currentEffect = pDynData->getEffectThread();
93 CAtmoInput *currentInput = pDynData->getLiveInput();
94 CAtmoPacketQueue *currentPacketQueue = pDynData->getLivePacketQueue();
97 if(oldEffectMode == emLivePicture) {
98 /* in case of disabling the live mode
99 first we have to stop the input
100 then the effect thread!
102 if(currentInput != NULL) {
103 pDynData->setLiveInput( NULL );
104 currentInput->Close();
110 // stop and delete/cleanup current Effect Thread...
111 pDynData->setEffectThread( NULL );
112 if(currentEffect != NULL) {
113 currentEffect->Terminate();
114 delete currentEffect;
115 currentEffect = NULL;
118 if(oldEffectMode == emLivePicture) {
120 and last we kill the PacketQueue used for communication between the threads
122 pDynData->setLivePacketQueue( NULL );
123 delete currentPacketQueue;
124 currentPacketQueue = NULL;
127 if((atmoConnection!=NULL) && (atmoConnection->isOpen()==ATMO_TRUE)) {
128 // neuen EffectThread nur mit aktiver Connection starten...
130 switch(newEffectMode) {
131 case emUndefined: // do nothing also in that case (avoid compiler warning)
136 case emStaticColor: {
137 // get values from config - and put them to all channels?
139 AllocColorPacket(packet, atmoConfig->getZoneCount());
140 for(int i=0; i < packet->numColors; i++){
141 packet->zone[i].r = atmoConfig->getStaticColor_Red();
142 packet->zone[i].g = atmoConfig->getStaticColor_Green();
143 packet->zone[i].b = atmoConfig->getStaticColor_Blue();
146 packet = CAtmoTools::ApplyGamma( atmoConfig, packet );
148 if(atmoConfig->isUseSoftwareWhiteAdj())
149 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
151 atmoConnection->SendData( packet );
158 case emLivePicture: {
159 currentEffect = new CAtmoLiveView(pDynData);
161 #if !defined(_ATMO_VLC_PLUGIN_)
162 CAtmoPacketQueueStatus *packetMon = NULL;
163 if(atmoConfig->getShow_statistics()) {
164 packetMon = new CAtmoPacketQueueStatus(pDynData->getHinstance(), (HWND)NULL);
165 packetMon->createWindow();
166 packetMon->showWindow(SW_SHOW);
168 currentPacketQueue = new CAtmoPacketQueue(packetMon);
169 pDynData->setLivePictureSource(lpsScreenCapture);
170 currentInput = new CAtmoGdiDisplayCaptureInput( pDynData );
172 currentPacketQueue = new CAtmoPacketQueue();
173 pDynData->setLivePictureSource(lpsExtern);
174 currentInput = new CAtmoExternalCaptureInput( pDynData );
179 #if !defined(_ATMO_VLC_PLUGIN_)
181 currentEffect = new CAtmoColorChanger(atmoConnection, atmoConfig);
184 case emLrColorChange:
185 currentEffect = new CAtmoLeftRightColorChanger(atmoConnection, atmoConfig);
192 atmoConfig->setEffectMode( newEffectMode );
194 pDynData->setLivePacketQueue( currentPacketQueue );
195 pDynData->setEffectThread( currentEffect );
196 pDynData->setLiveInput( currentInput );
198 if(currentEffect != NULL)
199 currentEffect->Run();
200 if(currentInput != NULL)
201 currentInput->Open();
203 pDynData->UnLockCriticalSection();
204 return oldEffectMode;
207 LivePictureSource CAtmoTools::SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource)
209 LivePictureSource oldSource;
210 pDynData->LockCriticalSection();
212 oldSource = pDynData->getLivePictureSource();
213 pDynData->setLivePictureSource( newLiveSource );
215 if ((pDynData->getAtmoConfig()->getEffectMode() == emLivePicture) &&
216 (pDynData->getEffectThread() != NULL) &&
217 (pDynData->getLivePacketQueue() != NULL))
219 CAtmoInput *input = pDynData->getLiveInput();
220 pDynData->setLiveInput( NULL );
227 switch(pDynData->getLivePictureSource()) {
228 case lpsDisabled: // do nothing in that case - avoid compiler warning
230 #if !defined(_ATMO_VLC_PLUGIN_)
231 case lpsScreenCapture:
232 input = new CAtmoGdiDisplayCaptureInput( pDynData );
236 input = new CAtmoExternalCaptureInput( pDynData );
240 pDynData->setLiveInput( input );
245 pDynData->UnLockCriticalSection();
249 ATMO_BOOL CAtmoTools::RecreateConnection(CAtmoDynData *pDynData)
251 pDynData->LockCriticalSection();
253 CAtmoConnection *current = pDynData->getAtmoConnection();
254 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
255 AtmoConnectionType act = atmoConfig->getConnectionType();
256 pDynData->setAtmoConnection(NULL);
257 if(current != NULL) {
258 current->CloseConnection();
263 case actClassicAtmo: {
264 CAtmoClassicConnection *tempConnection = new CAtmoClassicConnection( atmoConfig );
265 if(tempConnection->OpenConnection() == ATMO_FALSE) {
266 #if !defined(_ATMO_VLC_PLUGIN_)
267 if(atmoConfig->getIgnoreConnectionErrorOnStartup() == ATMO_FALSE)
269 char errorMsgBuf[200];
270 sprintf(errorMsgBuf,"Failed to open serial port com%d with errorcode: %d (0x%x)",
271 pDynData->getAtmoConfig()->getComport(),
272 tempConnection->getLastError(),
273 tempConnection->getLastError()
275 MessageBox(0,errorMsgBuf,"Error",MB_ICONERROR | MB_OK);
278 pDynData->setAtmoConnection(tempConnection);
280 pDynData->UnLockCriticalSection();
283 pDynData->setAtmoConnection(tempConnection);
284 pDynData->ReloadZoneDefinitionBitmaps();
286 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
288 CAtmoTools::SetChannelAssignment(pDynData,
289 atmoConfig->getCurrentChannelAssignment());
291 pDynData->UnLockCriticalSection();
295 #if !defined(_ATMO_VLC_PLUGIN_)
298 // actDummy8,actDummy12,actDummy16
299 CAtmoDummyConnection *tempConnection = new CAtmoDummyConnection(pDynData->getHinstance(),
301 if(tempConnection->OpenConnection() == ATMO_FALSE) {
302 pDynData->setAtmoConnection(tempConnection);
303 pDynData->UnLockCriticalSection();
306 pDynData->setAtmoConnection(tempConnection);
307 pDynData->ReloadZoneDefinitionBitmaps();
309 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
311 CAtmoTools::SetChannelAssignment(pDynData, pDynData->getAtmoConfig()->getCurrentChannelAssignment());
313 pDynData->UnLockCriticalSection();
319 // create here your DMX connections... instead of the dummy....
320 CAtmoDmxSerialConnection *tempConnection = new CAtmoDmxSerialConnection( atmoConfig );
321 if(tempConnection->OpenConnection() == ATMO_FALSE) {
322 pDynData->setAtmoConnection(tempConnection);
324 pDynData->UnLockCriticalSection();
327 pDynData->setAtmoConnection(tempConnection);
328 pDynData->ReloadZoneDefinitionBitmaps();
330 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
332 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
334 pDynData->UnLockCriticalSection();
338 #if !defined(_ATMO_VLC_PLUGIN_)
340 CAtmoNulConnection *tempConnection = new CAtmoNulConnection( atmoConfig );
341 if(tempConnection->OpenConnection() == ATMO_FALSE) {
342 pDynData->setAtmoConnection(tempConnection);
343 pDynData->UnLockCriticalSection();
346 pDynData->setAtmoConnection(tempConnection);
347 pDynData->ReloadZoneDefinitionBitmaps();
349 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
351 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
353 pDynData->UnLockCriticalSection();
359 CAtmoMultiConnection *tempConnection = new CAtmoMultiConnection( atmoConfig );
360 if(tempConnection->OpenConnection() == ATMO_FALSE) {
361 pDynData->setAtmoConnection(tempConnection);
362 pDynData->UnLockCriticalSection();
365 pDynData->setAtmoConnection(tempConnection);
366 pDynData->ReloadZoneDefinitionBitmaps();
368 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
370 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
372 pDynData->UnLockCriticalSection();
376 #if !defined(_ATMO_VLC_PLUGIN_)
377 case actMondolight: {
378 CMondolightConnection *tempConnection = new CMondolightConnection( atmoConfig );
379 if(tempConnection->OpenConnection() == ATMO_FALSE) {
380 pDynData->setAtmoConnection(tempConnection);
381 pDynData->UnLockCriticalSection();
384 pDynData->setAtmoConnection(tempConnection);
385 pDynData->ReloadZoneDefinitionBitmaps();
387 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
389 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
391 pDynData->UnLockCriticalSection();
396 CMoMoConnection *tempConnection = new CMoMoConnection( atmoConfig );
397 if(tempConnection->OpenConnection() == ATMO_FALSE) {
398 pDynData->setAtmoConnection(tempConnection);
399 pDynData->UnLockCriticalSection();
402 pDynData->setAtmoConnection(tempConnection);
403 pDynData->ReloadZoneDefinitionBitmaps();
405 tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
407 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
409 pDynData->UnLockCriticalSection();
413 case actFnordlicht: {
414 CFnordlichtConnection *tempConnection = new CFnordlichtConnection( atmoConfig );
415 if(tempConnection->OpenConnection() == ATMO_FALSE) {
416 pDynData->setAtmoConnection(tempConnection);
417 pDynData->UnLockCriticalSection();
420 pDynData->setAtmoConnection(tempConnection);
421 pDynData->ReloadZoneDefinitionBitmaps();
423 tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
425 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
427 pDynData->UnLockCriticalSection();
432 pDynData->UnLockCriticalSection();
438 pColorPacket CAtmoTools::WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
440 int w_adj_red = pAtmoConfig->getWhiteAdjustment_Red();
441 int w_adj_green = pAtmoConfig->getWhiteAdjustment_Green();
442 int w_adj_blue = pAtmoConfig->getWhiteAdjustment_Blue();
444 for (int i = 0; i < ColorPacket->numColors; i++) {
445 ColorPacket->zone[i].r = (unsigned char)(((int)w_adj_red * (int)ColorPacket->zone[i].r) / 255);
446 ColorPacket->zone[i].g = (unsigned char)(((int)w_adj_green * (int)ColorPacket->zone[i].g) / 255);
447 ColorPacket->zone[i].b = (unsigned char)(((int)w_adj_blue * (int)ColorPacket->zone[i].b) / 255);
452 pColorPacket CAtmoTools::ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
455 switch(pAtmoConfig->getSoftware_gamma_mode()) {
458 double GammaRed = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_red());
459 double GammaGreen = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_green());
460 double GammaBlue = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_blue());
461 for (int i = 0; i < ColorPacket->numColors; i++)
463 v = ColorPacket->zone[i].r;
464 v = (pow( v / 255.0f, GammaRed ) * 255.0f);
465 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
467 v = ColorPacket->zone[i].g;
468 v = (pow( v / 255.0f, GammaGreen ) * 255.0f);
469 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
471 v = ColorPacket->zone[i].b;
472 v = (pow( v / 255.0f, GammaBlue ) * 255.0f);
473 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
478 double Gamma = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_global());
479 for (int i = 0; i < ColorPacket->numColors; i++)
481 v = ColorPacket->zone[i].r;
482 v = (pow( v / 255.0f, Gamma ) * 255.0f);
483 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
485 v = ColorPacket->zone[i].g;
486 v = (pow( v / 255.0f, Gamma ) * 255.0f);
487 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
489 v = ColorPacket->zone[i].b;
490 v = (pow( v / 255.0f, Gamma ) * 255.0f);
491 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
499 int CAtmoTools::SetChannelAssignment(CAtmoDynData *pDynData, int index)
501 CAtmoConfig *pAtmoConfig = pDynData->getAtmoConfig();
502 CAtmoConnection *pAtmoConnection = pDynData->getAtmoConnection();
503 int oldIndex = pAtmoConfig->getCurrentChannelAssignment();
505 CAtmoChannelAssignment *ca = pAtmoConfig->getChannelAssignment(index);
506 if((ca!=NULL) && (pAtmoConnection!=NULL)) {
507 pAtmoConnection->SetChannelAssignment(ca);
508 pAtmoConfig->setCurrentChannelAssignment(index);
514 #if !defined(_ATMO_VLC_PLUGIN_)
516 void CAtmoTools::SaveBitmap(HDC hdc,HBITMAP hBmp,char *fileName) {
518 BITMAPFILEHEADER bmpFileHeader;
519 ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
520 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
522 GetDIBits(hdc,hBmp,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
523 if(bmpInfo.bmiHeader.biSizeImage<=0)
524 bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth * abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
525 void *pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
526 bmpInfo.bmiHeader.biCompression=BI_RGB;
528 GetDIBits(hdc,hBmp,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
531 bmpFileHeader.bfReserved1=0;
532 bmpFileHeader.bfReserved2=0;
533 bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
534 bmpFileHeader.bfType = MakeIntelWord('M','B');
535 bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
539 fp = fopen(fileName,"wb");
540 fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
541 fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
542 fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);