1 #include "wtf.h"
2 
3 #include <iostream>
4 #include <fstream>
5 #include <stdlib.h>
6 #include <sstream>
7 #include <QDir>
8 #include <QFileDialog>
9 #include <QMessageBox>
10 #include <QFile>
11 #include <QColorDialog>
12 #include <QTextStream>
13 #include <QInputDialog>
14 #include <QPainter>
15 #include <QImage>
16 
17 using namespace std;
18 
19 #ifndef DATADIR
20     #define DATADIR "./"
21 #endif
22 
23 #ifndef EXECPATH
24     #define EXECPATH "./osgg.bin"
25 #endif
26 
27 
on_btnStart_clicked()28 void mW::on_btnStart_clicked()
29 {
30   string cmdLine;
31 
32   /* Save settings */
33   saveSettings();
34 
35   cmdLine = "cd \"";
36   cmdLine += osggDataDir.toStdString();
37   cmdLine += "\" && \"";
38   cmdLine += osggExecPath.toStdString();
39   cmdLine += "\"";
40 
41   /** This HAS to be first because osgg only takes a int as argument 1 **/
42 
43   if( isDemo )
44   {
45     cmdLine += " --levelfile \"";
46     cmdLine += txtDemoLevel->text().toStdString();
47     cmdLine += "\"";
48     cmdLine += " --playdemo \"demos/"+lstDemo->currentItem()->text().toStdString() + "\"";
49 
50   } else {
51     if(tabLvl->currentIndex() == 1) //Custom level
52     {
53       /* Check that something is selected */
54       if(lstCustomLvl->currentRow() != -1)
55       {
56         cmdLine += " --levelfile \"";
57         cmdLine += osggUserDir.toStdString();
58         cmdLine += "/levels/";
59         cmdLine += osggCustomLevel.toStdString();
60         cmdLine += ".level\"";
61       } else {
62         QMessageBox info;
63         info.setText("Error: No level selected.");
64         info.exec();
65         return;
66       }
67 
68     } else { //std level
69       ostringstream t;
70       t.clear();
71       t << " " << numStartLevel->value();
72       cmdLine += t.str();
73     }
74   }
75 
76   if(runEditor)
77     cmdLine += " --edit";
78 
79   if(chIs->isChecked())
80     cmdLine += " --is";
81   if(chFullScreen->isChecked())
82     cmdLine += " --fullscreen";
83   if(!chZoom->isChecked())
84     cmdLine += " --nozoom";
85 
86 
87   if(!chVsync->isChecked())
88     cmdLine += " --sleep";
89 
90   if(chShowFps->isChecked())
91     cmdLine += " --showfps";
92 
93   if(!chSound->isChecked())
94     cmdLine += " --nosound";
95 
96   if(osggBackgroundColor != QString("000000"))
97   {
98     cmdLine += " --bgcolor ";
99     cmdLine += osggBackgroundColor.toStdString();
100   }
101 
102   //TODO: append --savedemo
103 
104 
105   FILE *stream;
106   QStringList output;
107   char buffer[2048];
108 
109   cout << "Running: " << cmdLine << endl << endl;
110   stream = popen(cmdLine.data(), "r");
111   while( fgets(buffer, 2048, stream) != NULL )
112   {
113     cout <<" osgg > " << buffer;
114     output << buffer;
115   }
116 
117   //if we were in the editor, let's refresh the preview
118   if( runEditor )
119   {
120       preview( (osggUserDir.toStdString()+"/levels/"+osggCustomLevel.toStdString()+".level").data() );
121   }
122 
123   //Clear isDemo and runEditor
124   isDemo=0;
125   runEditor=0;
126 }
127 
128 /* Populate tables */
listLevels()129 void mW::listLevels()
130 {
131   QStringList filter;
132   QFileInfoList fileInfoList;
133   QString name;
134 
135   lstStdLvl->clear();
136   lstCustomLvl->clear();
137 
138   filter << "*.level";
139   QDir qd(osggDataDir+"/levels/");
140   qd.setNameFilters(filter);
141   /* Standard Levels */
142   if( qd.exists() )
143   {
144     fileInfoList = qd.entryInfoList();
145     int i;
146     for(i=0; i < fileInfoList.size(); i++)
147     {
148       name.sprintf("%03i", i);
149       lstStdLvl->insertItem(0, name);
150     }
151     numStartLevel->setMaximum(i-1);
152 
153     lstStdLvl->sortItems(Qt::AscendingOrder);
154   } else {
155     QMessageBox info;
156     info.setText("Standard level dir '"+osggDataDir+"levels/' does not exist, check settings.");
157     info.exec();
158   }
159 
160   /* Custom (user) levels */
161   qd.cd(osggUserDir+"/levels/");
162   if( qd.exists() )
163   {
164     fileInfoList = qd.entryInfoList();
165     int i;
166     for(i=0; i < fileInfoList.size(); i++)
167     {
168       name = fileInfoList.at(i).fileName();
169       name = name.left( name.indexOf('.') );
170       lstCustomLvl->insertItem(0, name );
171     }
172 
173 
174   }
175 
176 }
177 
178 /* Populate tables */
listDemos()179 void mW::listDemos()
180 {
181   QStringList filter;
182   QFileInfoList fileInfoList;
183 
184   filter << "*.bin";
185   QDir qd(osggDataDir+"/demos/");
186   qd.setNameFilters(filter);
187 
188   if( qd.exists() )
189   {
190     fileInfoList = qd.entryInfoList();
191     int i;
192     for(i=0; i < fileInfoList.size(); i++)
193     {
194       QFileInfo fileInfo = fileInfoList.at(i);
195       QString name = fileInfo.fileName();
196       lstDemo->insertItem(0, name );
197     }
198 
199     lstDemo->sortItems(Qt::AscendingOrder);
200   } else {
201     QMessageBox info;
202     info.setText("Demo dir '"+osggDataDir+"demos/' does not exist, check settings.");
203     info.exec();
204   }
205 
206 }
207 
208 
209 
saveSettings()210 void mW::saveSettings()
211 {
212   QDir qd(osggUserDir);
213 
214   if( qd.exists() )
215   {
216     QFile cfgFile( osggUserDir+"/osgglaunch.cfg" );
217     if(cfgFile.open(QFile::WriteOnly | QFile::Truncate) )
218     {
219       QTextStream t(&cfgFile);
220       t <<"dataDir="<<osggDataDir<<endl;
221       t << "execPath="<<osggExecPath << endl;
222       t << "soundOff=" << chSound->isChecked() << endl;
223       t << "fullScreen=" << chFullScreen->isChecked() << endl;
224       t << "bgColor="<<osggBackgroundColor << endl;
225       t << "vsync="<<chVsync->isChecked() << endl;
226       t << "showfps=" << chShowFps->isChecked() << endl;
227       cfgFile.close();
228     }
229   }
230 }
231 
loadSettings()232 void mW::loadSettings()
233 {
234   osggDataDir=DATADIR;
235   osggExecPath=EXECPATH;
236 
237   osggUserDir=QDir::homePath();
238   osggUserDir.append("/.osgg");
239 
240   osggBackgroundColor="000000";
241 
242   QDir qd(osggUserDir);
243 
244   if(qd.exists(osggUserDir))
245   {
246     /* Open Settings file */
247     QString fileName = osggUserDir+"/osgglaunch.cfg";
248 
249     ifstream conf;
250     string line,set,val;
251     conf.open( fileName.toStdString().data() );
252     if(conf.is_open())
253     {
254       while(!conf.eof())
255       {
256         getline(conf, line);
257         if(line.find('=') != string::npos)
258         {
259           set=line.substr(0,line.find('='));
260           val=line.substr(line.find('=')+1);
261 
262           if(set=="dataDir")
263           {
264             osggDataDir = val.data();
265             cout << "Using datadir from " << fileName.toStdString() << ": " << osggDataDir.toStdString() << endl;
266           } else if(set=="execPath")
267           {
268             osggExecPath = val.data();
269             cout << "Using execpath from " << fileName.toStdString() << ": " << osggExecPath.toStdString() << endl;
270           } else if(set=="is")
271           {
272             chIs->setChecked( atoi(val.data()) );
273           } else if(set=="soundOff")
274           {
275             chSound->setChecked( atoi(val.data()) );
276           } else if(set=="fullScreen")
277           {
278             chFullScreen->setChecked( atoi(val.data()) );
279           } else if(set=="bgColor")
280           {
281             osggBackgroundColor=val.data();
282             int r,g,b;
283             char rgb[5];
284             sprintf(rgb,"0x%c%c", osggBackgroundColor.at(0).toAscii(), osggBackgroundColor.at(1).toAscii() );
285             r=strtol(rgb, NULL, 16);
286             sprintf(rgb,"0x%c%c", osggBackgroundColor.at(2).toAscii(), osggBackgroundColor.at(3).toAscii() );
287             g=strtol(rgb, NULL, 16);
288             sprintf(rgb,"0x%c%c", osggBackgroundColor.at(4).toAscii(), osggBackgroundColor.at(5).toAscii() );
289             b=strtol(rgb, NULL, 16);
290             QString bgColorStyleSheet;
291             char sh[64];
292             sprintf(sh, "background-color: rgb(%i, %i, %i);", r,g,b);
293             bgColorStyleSheet=sh;
294             btnSelectBgColor->setStyleSheet(bgColorStyleSheet);
295           } else if(set=="showfps")
296           {
297             chShowFps->setChecked( atoi(val.data()) );
298           } else if(set=="vsync")
299           {
300             chVsync->setChecked( atoi(val.data()) );
301           }
302         }
303       }
304       conf.close();
305     }
306 
307   } else {
308     QMessageBox info;
309     if(qd.mkdir(osggUserDir))
310     {
311       info.setText("Created directory in '"+osggUserDir+"'");
312       qd.mkdir(osggUserDir+"/levels/");
313       qd.mkdir(osggUserDir+"/demos/");
314     } else {
315       info.setText("Could not create directory in '"+osggUserDir+"'");
316     }
317     info.exec();
318   }
319 
320 }
321 
refreshSettings()322 void mW::refreshSettings()
323 {
324   txtExecPath->setText(osggExecPath);
325   txtDataDir->setText(osggDataDir);
326 }
327 
on_btnBrowseDataDir_clicked()328 void mW::on_btnBrowseDataDir_clicked()
329 {
330   QFileDialog fd(this);
331   fd.setFileMode(QFileDialog::DirectoryOnly);
332   if(fd.exec())
333   {
334     QStringList dir = fd.selectedFiles();
335     osggDataDir = dir.at(0);
336     if(osggDataDir.at( osggDataDir.length()-1 ) != '/')
337     {
338       osggDataDir+="/";
339     }
340     refreshSettings();
341     listLevels();
342   }
343 }
344 
on_btnDemoBrowse_clicked()345 void mW::on_btnDemoBrowse_clicked()
346 {
347   QFileDialog fd(this);
348   fd.setFileMode(QFileDialog::ExistingFile);
349   if(fd.exec())
350   {
351     QStringList dir = fd.selectedFiles();
352     txtDemoLevel->setText( dir.at(0) );
353   }
354 }
on_btnPlayDemo_clicked()355 void mW::on_btnPlayDemo_clicked()
356 {
357   QMessageBox info;
358   //Check that the filelist is not empty
359   if( lstDemo->count() < 1 )
360   {
361       info.setText("No demos found in the demo dir.");
362       info.exec();
363       return;
364   }
365 
366   QListWidgetItem *item =  lstDemo->currentItem();
367   //Check that a demo has been selected
368   if( item->text().length() == 0 )
369   {
370       info.setText("No demo selected.");
371       info.exec();
372   }
373 
374   //Check that a demo-level has been selected
375   if( txtDemoLevel->text().length() < 3  )
376   {
377       info.setText("No level selected to play demo inside.");
378       info.exec();
379       return;
380   }
381 
382   //Set "isDemo" and call
383   isDemo=1;
384   on_btnStart_clicked();
385 }
386 
on_btnBrowseExecPath_clicked()387 void mW::on_btnBrowseExecPath_clicked()
388 {
389   QFileDialog fd(this);
390   fd.setFileMode(QFileDialog::ExistingFile);
391   if(fd.exec())
392   {
393     QStringList dir = fd.selectedFiles();
394     osggExecPath = dir.at(0);
395     refreshSettings();
396   }
397 }
398 
on_btnSelectBgColor_clicked()399 void mW::on_btnSelectBgColor_clicked()
400 {
401   int r,g,b;
402   QColor myColor;
403   myColor.setRgba(QColorDialog::getRgba(0x00));
404   myColor.getRgb(&r,&g,&b);
405 
406   QString bgColorStyleSheet;
407   char sh[64];
408   sprintf(sh, "background-color: rgb(%i, %i, %i);", r,g,b);
409   bgColorStyleSheet=sh;
410   btnSelectBgColor->setStyleSheet(bgColorStyleSheet);
411   sprintf(sh, "%02x%02x%02x",r,g,b);
412   osggBackgroundColor=sh;
413 }
414 
on_lstCustomLvl_currentTextChanged(QString text)415 void mW::on_lstCustomLvl_currentTextChanged(QString text)
416 {
417   osggCustomLevel = text;
418 
419   ostringstream t;
420   t.clear();
421   t << osggUserDir.toStdString() << "/levels/" << osggCustomLevel.toStdString() << ".level";
422   preview( t.str().data() );
423 
424 }
425 
on_numStartLevel_valueChanged(int l)426 void mW::on_numStartLevel_valueChanged(int l)
427 {
428   lstStdLvl->setCurrentRow(l);
429 
430   ostringstream t;
431   t.clear();
432   t <<  osggDataDir.toStdString() <<"/levels/" << numStartLevel->value() << ".level";
433   preview( t.str().data());
434 }
435 
preview(const char * file)436 void mW::preview(const char* file)
437 {
438     if(pScene)
439     {
440         delete pScene;
441     }
442     pScene = new lvlPrevScene();
443     pScene->load(file);
444 
445     lvlPreview->setScene( pScene );
446 }
447 
on_btnAddCustom_clicked()448 void mW::on_btnAddCustom_clicked()
449 {
450   QString lvl;
451   /* Browse for the file */
452   QFileDialog fd(this);
453   fd.setNameFilter("*.level");
454   fd.setFileMode(QFileDialog::ExistingFile);
455   if(fd.exec())
456   {
457     /* Copy file to home/.osgg/levels */
458     QStringList dir = fd.selectedFiles();
459     lvl= dir.at(0);
460     QFile lvlFile(lvl);
461     if(lvlFile.exists())
462     {
463       QFileInfo fi(lvlFile);
464       if(lvlFile.copy( osggUserDir+"/levels/"+fi.fileName() ) )
465       {
466         /* Update list */
467         listLevels();
468       } else {
469         QMessageBox info;
470         info.setText("Could not copy file to levels directory..");
471         info.exec();
472       }
473     }
474 
475   }
476 
477 }
478 
on_btnRemoveCustom_clicked()479 void mW::on_btnRemoveCustom_clicked()
480 {
481   if(lstCustomLvl->currentRow() != -1)
482   {
483     QFile levelfile( osggUserDir+"/levels/"+osggCustomLevel+".level" );
484     if(!levelfile.remove())
485     {
486       QMessageBox info;
487       info.setText("Could not delete file..");
488       info.exec();
489     } else {
490       listLevels();
491     }
492   }
493 }
494 
on_txtDataDir_textChanged(QString s)495 void mW::on_txtDataDir_textChanged(QString s)
496 {
497   osggDataDir = s;
498 }
499 
on_txtExecPath_textChanged(QString s)500 void mW::on_txtExecPath_textChanged(QString s)
501 {
502   osggExecPath = s;
503 }
504 
on_btnCreate_clicked()505 void mW::on_btnCreate_clicked()
506 {
507   bool ok=0;
508   QMessageBox info;
509   QString lvl = QInputDialog::getText(this, tr("Create New Level"), tr("Enter Level Name"), QLineEdit::Normal, "NewLevel", &ok);
510   if(ok)
511   {
512     osggCustomLevel = lvl;
513     QFile newLvl( osggUserDir + "/levels/" + osggCustomLevel + ".level" );
514     if(newLvl.exists())
515     {
516       info.setText("Error: File exists!");
517       info.exec();
518       return;
519     }
520 
521 
522     /* Write a small standard file */
523     QString ld;
524     ld = "StartEntity\n0\n0\n1\n90\n-1\nEndEntity\nStartEntity\n2.43333\n0.953333\n2\n90\n1\nEndEntity\n";
525     if( newLvl.open(QIODevice::WriteOnly) )
526     {
527       newLvl.write( ld.toAscii() );
528       newLvl.close();
529     } else {
530       info.setText("Error: Could not open file for write.");
531       info.exec();
532       return;
533     }
534     /* Refresh list */
535     listLevels();
536     osggCustomLevel = lvl;
537     /* Find the new level */
538     QList<QListWidgetItem *> list = lstCustomLvl->findItems( osggCustomLevel,Qt::MatchFixedString );
539     /* Set it */
540     lstCustomLvl->setCurrentItem( list.at(0) );
541     //Run it
542     runEditor=1;
543     on_btnStart_clicked();
544 
545   }
546 }
547 
on_btnEdit_clicked()548 void mW::on_btnEdit_clicked()
549 {
550     runEditor=1;
551     on_btnStart_clicked();
552 }
553 
554 
on_tabLvlCurrentChanged(int index)555 void mW::on_tabLvlCurrentChanged(int index)
556 {
557     if(index==0)
558     {
559         //Standard level
560         on_numStartLevel_valueChanged( lstStdLvl->currentRow() );
561     } else if (index==1)
562     {
563         //If the list is not empty
564         if( lstCustomLvl->count() > 0 )
565         {
566             //If nothing is yet selected
567             if( lstCustomLvl->selectedItems().count() == 0 )
568             {
569                 lstCustomLvl->setCurrentRow(0);
570             }
571             QString lvlName = osggUserDir+ "/levels/"+ lstCustomLvl->selectedItems().at(0)->text()+".level";
572             preview( lvlName.toStdString().data() );
573 	}
574     }
575 }
576 
mW(QMainWindow * p)577 mW::mW(QMainWindow* p) : QMainWindow(p)
578 {
579   pScene=NULL;
580   setupUi(p);
581 
582   loadSettings();
583   refreshSettings();
584 
585   listLevels();
586   listDemos();
587 
588   QObject::connect(txtDataDir, SIGNAL(textChanged(QString)), this, SLOT(on_txtDataDir_textChanged(QString)));
589   QObject::connect(txtExecPath, SIGNAL(textChanged(QString)), this, SLOT(on_txtExecPath_textChanged(QString)));
590   QObject::connect(btnStart, SIGNAL(clicked()), this, SLOT(on_btnStart_clicked()));
591   QObject::connect(btnBrowseDataDir, SIGNAL(clicked()), this, SLOT(on_btnBrowseDataDir_clicked()));
592   QObject::connect(btnBrowseExecPath, SIGNAL(clicked()), this, SLOT(on_btnBrowseExecPath_clicked()));
593   QObject::connect(btnSelectBgColor, SIGNAL(clicked()), this, SLOT(on_btnSelectBgColor_clicked()));
594   QObject::connect(numStartLevel, SIGNAL(valueChanged(int)), this, SLOT(on_numStartLevel_valueChanged(int)));
595   QObject::connect(lstCustomLvl, SIGNAL(currentTextChanged(QString)), this, SLOT(on_lstCustomLvl_currentTextChanged(QString)));
596   QObject::connect(btnAddCustom, SIGNAL(clicked()), this, SLOT(on_btnAddCustom_clicked()));
597   QObject::connect(btnRemoveCustom, SIGNAL(clicked()), this, SLOT(on_btnRemoveCustom_clicked()));
598   QObject::connect(btnCreate, SIGNAL(clicked()), this, SLOT(on_btnCreate_clicked()));
599   QObject::connect(btnEdit, SIGNAL(clicked()), this, SLOT(on_btnEdit_clicked()));
600 
601   QObject::connect(btnDemoBrowse, SIGNAL(clicked()), this, SLOT(on_btnDemoBrowse_clicked()));
602   QObject::connect(btnPlayDemo, SIGNAL(clicked()), this, SLOT(on_btnPlayDemo_clicked()));
603 
604   QObject::connect(tabLvl, SIGNAL(currentChanged(int)), this, SLOT(on_tabLvlCurrentChanged(int)) );
605 
606   lvlPreview->scale(0.5, -0.5);
607   lvlPreview->setRenderHints(QPainter::Antialiasing);
608 
609   on_numStartLevel_valueChanged(0);
610   isDemo=0;
611   runEditor=0;
612 }
613 
~mW()614 mW::~mW()
615 {
616   saveSettings();
617 }
618