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 "AtmoExternalCaptureInput.h"
19 #if !defined(_ATMO_VLC_PLUGIN_)
20 # include "AtmoColorChanger.h"
21 # include "AtmoLeftRightColorChanger.h"
23 # include "AtmoDummyConnection.h"
24 # include "AtmoNulConnection.h"
25 # include "MondolightConnection.h"
27 # include "AtmoGdiDisplayCaptureInput.h"
31 CAtmoTools::CAtmoTools(void)
35 CAtmoTools::~CAtmoTools(void)
39 void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
41 pDynData->LockCriticalSection();
44 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
45 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
46 if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) {
49 AllocColorPacket(packet, atmoConfig->getZoneCount());
51 // set a special color? on shutdown of the software? mostly may use black or so ...
52 // if this function ist disabled ... atmo will continuing to show the last color...
53 for(i = 0; i < packet->numColors; i++) {
54 packet->zone[i].r = atmoConfig->getShutdownColor_Red();
55 packet->zone[i].g = atmoConfig->getShutdownColor_Green();
56 packet->zone[i].b = atmoConfig->getShutdownColor_Blue();
59 packet = CAtmoTools::ApplyGamma(atmoConfig, packet);
61 if(atmoConfig->isUseSoftwareWhiteAdj())
62 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
64 atmoConnection->SendData(packet);
66 delete (char *)packet;
70 pDynData->UnLockCriticalSection();
73 EffectMode CAtmoTools::SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode)
75 // may need a critical section??
76 if(pDynData == NULL) {
79 pDynData->LockCriticalSection();
81 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
82 if(atmoConfig == NULL) {
83 pDynData->UnLockCriticalSection();
86 CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
88 EffectMode oldEffectMode = atmoConfig->getEffectMode();
89 CThread *currentEffect = pDynData->getEffectThread();
90 CAtmoInput *currentInput = pDynData->getLiveInput();
91 CAtmoPacketQueue *currentPacketQueue = pDynData->getLivePacketQueue();
94 if(oldEffectMode == emLivePicture) {
95 /* in case of disabling the live mode
96 first we have to stop the input
97 then the effect thread!
99 if(currentInput != NULL) {
100 pDynData->setLiveInput( NULL );
101 currentInput->Close();
107 // stop and delete/cleanup current Effect Thread...
108 pDynData->setEffectThread( NULL );
109 if(currentEffect != NULL) {
110 currentEffect->Terminate();
111 delete currentEffect;
112 currentEffect = NULL;
115 if(oldEffectMode == emLivePicture) {
117 and last we kill the PacketQueue used for communication between the threads
119 pDynData->setLivePacketQueue( NULL );
120 delete currentPacketQueue;
121 currentPacketQueue = NULL;
124 if((atmoConnection!=NULL) && (atmoConnection->isOpen()==ATMO_TRUE)) {
125 // neuen EffectThread nur mit aktiver Connection starten...
127 switch(newEffectMode) {
131 case emStaticColor: {
132 // get values from config - and put them to all channels?
134 AllocColorPacket(packet, atmoConfig->getZoneCount());
135 for(int i=0; i < packet->numColors; i++){
136 packet->zone[i].r = atmoConfig->getStaticColor_Red();
137 packet->zone[i].g = atmoConfig->getStaticColor_Green();
138 packet->zone[i].b = atmoConfig->getStaticColor_Blue();
141 packet = CAtmoTools::ApplyGamma( atmoConfig, packet );
143 if(atmoConfig->isUseSoftwareWhiteAdj())
144 packet = CAtmoTools::WhiteCalibration(atmoConfig, packet);
146 atmoConnection->SendData( packet );
148 delete (char *)packet;
153 case emLivePicture: {
154 currentEffect = new CAtmoLiveView(pDynData);
156 #if !defined(_ATMO_VLC_PLUGIN_)
157 CAtmoPacketQueueStatus *packetMon = NULL;
158 if(atmoConfig->getShow_statistics()) {
159 packetMon = new CAtmoPacketQueueStatus(pDynData->getHinstance(), (HWND)NULL);
160 packetMon->createWindow();
161 packetMon->showWindow(SW_SHOW);
163 currentPacketQueue = new CAtmoPacketQueue(packetMon);
164 pDynData->setLivePictureSource(lpsScreenCapture);
165 currentInput = new CAtmoGdiDisplayCaptureInput( pDynData );
167 currentPacketQueue = new CAtmoPacketQueue();
168 pDynData->setLivePictureSource(lpsExtern);
169 currentInput = new CAtmoExternalCaptureInput( pDynData );
174 #if !defined(_ATMO_VLC_PLUGIN_)
176 currentEffect = new CAtmoColorChanger(atmoConnection, atmoConfig);
179 case emLrColorChange:
180 currentEffect = new CAtmoLeftRightColorChanger(atmoConnection, atmoConfig);
187 atmoConfig->setEffectMode( newEffectMode );
189 pDynData->setLivePacketQueue( currentPacketQueue );
190 pDynData->setEffectThread( currentEffect );
191 pDynData->setLiveInput( currentInput );
193 if(currentEffect != NULL)
194 currentEffect->Run();
195 if(currentInput != NULL)
196 currentInput->Open();
198 pDynData->UnLockCriticalSection();
199 return oldEffectMode;
202 LivePictureSource CAtmoTools::SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource)
204 LivePictureSource oldSource;
205 pDynData->LockCriticalSection();
207 oldSource = pDynData->getLivePictureSource();
208 pDynData->setLivePictureSource( newLiveSource );
210 if ((pDynData->getAtmoConfig()->getEffectMode() == emLivePicture) &&
211 (pDynData->getEffectThread() != NULL) &&
212 (pDynData->getLivePacketQueue() != NULL))
214 CAtmoInput *input = pDynData->getLiveInput();
215 pDynData->setLiveInput( NULL );
222 switch(pDynData->getLivePictureSource()) {
223 #if !defined(_ATMO_VLC_PLUGIN_)
224 case lpsScreenCapture:
225 input = new CAtmoGdiDisplayCaptureInput( pDynData );
229 input = new CAtmoExternalCaptureInput( pDynData );
233 pDynData->setLiveInput( input );
238 pDynData->UnLockCriticalSection();
242 ATMO_BOOL CAtmoTools::RecreateConnection(CAtmoDynData *pDynData)
244 pDynData->LockCriticalSection();
246 CAtmoConnection *current = pDynData->getAtmoConnection();
247 CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
248 AtmoConnectionType act = atmoConfig->getConnectionType();
249 pDynData->setAtmoConnection(NULL);
250 if(current != NULL) {
251 current->CloseConnection();
256 case actClassicAtmo: {
257 CAtmoClassicConnection *tempConnection = new CAtmoClassicConnection( atmoConfig );
258 if(tempConnection->OpenConnection() == ATMO_FALSE) {
259 #if !defined(_ATMO_VLC_PLUGIN_)
260 if(atmoConfig->getIgnoreConnectionErrorOnStartup() == ATMO_FALSE)
262 char errorMsgBuf[200];
263 sprintf(errorMsgBuf,"Failed to open serial port com%d with errorcode: %d (0x%x)",
264 pDynData->getAtmoConfig()->getComport(),
265 tempConnection->getLastError(),
266 tempConnection->getLastError()
268 MessageBox(0,errorMsgBuf,"Error",MB_ICONERROR | MB_OK);
271 pDynData->setAtmoConnection(tempConnection);
273 pDynData->UnLockCriticalSection();
276 pDynData->setAtmoConnection(tempConnection);
277 pDynData->ReloadZoneDefinitionBitmaps();
279 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
281 CAtmoTools::SetChannelAssignment(pDynData,
282 atmoConfig->getCurrentChannelAssignment());
284 pDynData->UnLockCriticalSection();
288 #if !defined(_ATMO_VLC_PLUGIN_)
291 // actDummy8,actDummy12,actDummy16
292 CAtmoDummyConnection *tempConnection = new CAtmoDummyConnection(pDynData->getHinstance(),
294 if(tempConnection->OpenConnection() == ATMO_FALSE) {
295 pDynData->setAtmoConnection(tempConnection);
296 pDynData->UnLockCriticalSection();
299 pDynData->setAtmoConnection(tempConnection);
300 pDynData->ReloadZoneDefinitionBitmaps();
302 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
304 CAtmoTools::SetChannelAssignment(pDynData, pDynData->getAtmoConfig()->getCurrentChannelAssignment());
306 pDynData->UnLockCriticalSection();
312 // create here your DMX connections... instead of the dummy....
313 CAtmoDmxSerialConnection *tempConnection = new CAtmoDmxSerialConnection( atmoConfig );
314 if(tempConnection->OpenConnection() == ATMO_FALSE) {
315 pDynData->setAtmoConnection(tempConnection);
317 pDynData->UnLockCriticalSection();
320 pDynData->setAtmoConnection(tempConnection);
321 pDynData->ReloadZoneDefinitionBitmaps();
323 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
325 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
327 pDynData->UnLockCriticalSection();
331 #if !defined(_ATMO_VLC_PLUGIN_)
333 CAtmoNulConnection *tempConnection = new CAtmoNulConnection( atmoConfig );
334 if(tempConnection->OpenConnection() == ATMO_FALSE) {
335 pDynData->setAtmoConnection(tempConnection);
336 pDynData->UnLockCriticalSection();
339 pDynData->setAtmoConnection(tempConnection);
340 pDynData->ReloadZoneDefinitionBitmaps();
342 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
344 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
346 pDynData->UnLockCriticalSection();
352 CAtmoMultiConnection *tempConnection = new CAtmoMultiConnection( atmoConfig );
353 if(tempConnection->OpenConnection() == ATMO_FALSE) {
354 pDynData->setAtmoConnection(tempConnection);
355 pDynData->UnLockCriticalSection();
358 pDynData->setAtmoConnection(tempConnection);
359 pDynData->ReloadZoneDefinitionBitmaps();
361 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
363 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
365 pDynData->UnLockCriticalSection();
369 #if !defined(_ATMO_VLC_PLUGIN_)
370 case actMondolight: {
371 CMondolightConnection *tempConnection = new CMondolightConnection( atmoConfig );
372 if(tempConnection->OpenConnection() == ATMO_FALSE) {
373 pDynData->setAtmoConnection(tempConnection);
374 pDynData->UnLockCriticalSection();
377 pDynData->setAtmoConnection(tempConnection);
378 pDynData->ReloadZoneDefinitionBitmaps();
380 tempConnection->CreateDefaultMapping(atmoConfig->getChannelAssignment(0));
382 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment());
384 pDynData->UnLockCriticalSection();
389 CMoMoConnection *tempConnection = new CMoMoConnection( atmoConfig );
390 if(tempConnection->OpenConnection() == ATMO_FALSE) {
391 pDynData->setAtmoConnection(tempConnection);
392 pDynData->UnLockCriticalSection();
395 pDynData->setAtmoConnection(tempConnection);
396 pDynData->ReloadZoneDefinitionBitmaps();
398 tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
400 CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
402 pDynData->UnLockCriticalSection();
407 pDynData->UnLockCriticalSection();
413 pColorPacket CAtmoTools::WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
415 int w_adj_red = pAtmoConfig->getWhiteAdjustment_Red();
416 int w_adj_green = pAtmoConfig->getWhiteAdjustment_Green();
417 int w_adj_blue = pAtmoConfig->getWhiteAdjustment_Blue();
419 for (int i = 0; i < ColorPacket->numColors; i++) {
420 ColorPacket->zone[i].r = (unsigned char)(((int)w_adj_red * (int)ColorPacket->zone[i].r) / 255);
421 ColorPacket->zone[i].g = (unsigned char)(((int)w_adj_green * (int)ColorPacket->zone[i].g) / 255);
422 ColorPacket->zone[i].b = (unsigned char)(((int)w_adj_blue * (int)ColorPacket->zone[i].b) / 255);
427 pColorPacket CAtmoTools::ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket)
430 switch(pAtmoConfig->getSoftware_gamma_mode()) {
433 double GammaRed = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_red());
434 double GammaGreen = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_green());
435 double GammaBlue = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_blue());
436 for (int i = 0; i < ColorPacket->numColors; i++)
438 v = ColorPacket->zone[i].r;
439 v = (pow( v / 255.0f, GammaRed ) * 255.0f);
440 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
442 v = ColorPacket->zone[i].g;
443 v = (pow( v / 255.0f, GammaGreen ) * 255.0f);
444 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
446 v = ColorPacket->zone[i].b;
447 v = (pow( v / 255.0f, GammaBlue ) * 255.0f);
448 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
453 double Gamma = 10.0 / ((double)pAtmoConfig->getSoftware_gamma_global());
454 for (int i = 0; i < ColorPacket->numColors; i++)
456 v = ColorPacket->zone[i].r;
457 v = (pow( v / 255.0f, Gamma ) * 255.0f);
458 ColorPacket->zone[i].r = ATMO_MIN((int)v, 255);
460 v = ColorPacket->zone[i].g;
461 v = (pow( v / 255.0f, Gamma ) * 255.0f);
462 ColorPacket->zone[i].g = ATMO_MIN((int)v, 255);
464 v = ColorPacket->zone[i].b;
465 v = (pow( v / 255.0f, Gamma ) * 255.0f);
466 ColorPacket->zone[i].b = ATMO_MIN((int)v, 255);
474 int CAtmoTools::SetChannelAssignment(CAtmoDynData *pDynData, int index)
476 CAtmoConfig *pAtmoConfig = pDynData->getAtmoConfig();
477 CAtmoConnection *pAtmoConnection = pDynData->getAtmoConnection();
478 int oldIndex = pAtmoConfig->getCurrentChannelAssignment();
480 CAtmoChannelAssignment *ca = pAtmoConfig->getChannelAssignment(index);
481 if((ca!=NULL) && (pAtmoConnection!=NULL)) {
482 pAtmoConnection->SetChannelAssignment(ca);
483 pAtmoConfig->setCurrentChannelAssignment(index);
489 #if !defined(_ATMO_VLC_PLUGIN_)
491 void CAtmoTools::SaveBitmap(HDC hdc,HBITMAP hBmp,char *fileName) {
493 BITMAPFILEHEADER bmpFileHeader;
494 ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
495 bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
497 GetDIBits(hdc,hBmp,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
498 if(bmpInfo.bmiHeader.biSizeImage<=0)
499 bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth * abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
500 void *pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
501 bmpInfo.bmiHeader.biCompression=BI_RGB;
503 GetDIBits(hdc,hBmp,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
506 bmpFileHeader.bfReserved1=0;
507 bmpFileHeader.bfReserved2=0;
508 bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
509 bmpFileHeader.bfType = MakeIntelWord('M','B');
510 bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
514 fp = fopen(fileName,"wb");
515 fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
516 fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
517 fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);