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