~ubuntu-branches/ubuntu/saucy/enigma/saucy

« back to all changes in this revision

Viewing changes to src/main.cc

  • Committer: Package Import Robot
  • Author(s): Erich Schubert
  • Date: 2013-04-06 14:54:02 UTC
  • mfrom: (5.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20130406145402-rr1c80vtxjf4ewm7
Tags: 1.20-dfsg.1-1
* New upstream release (Closes: #704595)
  (Repacked: dropped zipios++ source and main menu music)
* Update watch file, sf.net again.
* Fix documentation links (Closes: #653508)
* Conflict with enigma-level-previews to encourage deinstallation
  (Pregenerated level previews were only used with version 1.01)
* Use dh7 for building instead of CDBS
* Update to policy 3.9.4.0 (no changes)
* Register documentation with doc-base

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
18
 *
19
19
 */
20
 
 
21
20
#include "main.hh"
22
21
#include "display.hh"
23
22
#include "lua.hh"
59
58
#include <xercesc/util/XMLUniDefs.hpp>
60
59
#include <xercesc/util/PlatformUtils.hpp>
61
60
#include <xercesc/util/XercesVersion.hpp>
 
61
#include "SDL_main.h"
62
62
#include <SDL_image.h>
63
63
#include <SDL_mixer.h>
64
64
#include <SDL_ttf.h>
74
74
using namespace std;
75
75
using namespace ecl;
76
76
using namespace enigma;
77
 
XERCES_CPP_NAMESPACE_USE 
 
77
XERCES_CPP_NAMESPACE_USE
78
78
 
79
79
#ifdef WIN32
80
80
// LoadImage is a Syscall on Windows, which gets defined to LoadImageA
94
94
namespace enigma
95
95
{
96
96
    Application app;
97
 
    
 
97
 
98
98
    bool noAssert = true;      // block expensive assert evaluations by default
99
99
 
100
100
    bool   WizardMode        = false;
106
106
 
107
107
/*! The stream object that is used for logging messages.  As defined
108
108
  here, it is not connected to any file or buffer.
109
 
  
 
109
 
110
110
  (Note: I think writing to a stream without a streambuffer *should*
111
111
  be a no-op, but it leads to crashes with g++ 2.95.  to circumvent
112
112
  this, Log is initialized with a dummy streambuf in init(). ) */
169
169
 
170
170
        void on_option (int id, const string &param);
171
171
        void on_argument (const string &arg);
172
 
 
173
172
    };
174
173
}
175
174
 
201
200
    def (OPT_PREF,              "pref", 'p', true);
202
201
}
203
202
 
204
 
void AP::on_option (int id, const string &param) 
 
203
void AP::on_option (int id, const string &param)
205
204
{
206
205
    switch (id) {
207
206
    case OPT_GAME:
208
 
        gamename = param; 
 
207
        gamename = param;
209
208
        break;
210
209
    case OPT_DATA:
211
210
// we should be able to add several paths -- file.cc has does not yet support this
223
222
    }
224
223
}
225
224
 
226
 
void AP::on_argument (const string &arg) 
 
225
void AP::on_argument (const string &arg)
227
226
{
228
227
    levelnames.push_back (arg);
229
228
}
243
242
}
244
243
 
245
244
 
246
 
void Application::init(int argc, char **argv) 
 
245
void Application::init(int argc, char **argv)
247
246
{
248
247
    sscanf(PACKAGE_VERSION, "%4lf", &enigmaVersion);
249
248
 
257
256
    if (CFStringGetFileSystemRepresentation(cffileStr, localbuffer, cfmax)) {
258
257
      progCallPath = localbuffer; // error skips this and defaults to argv[0] which works for most purposes
259
258
    }
260
 
    CFRelease(mainBundle);
261
259
    CFRelease(cfurlmain);
262
260
    CFRelease(cffileStr);
263
261
#endif
264
 
    copy(argv+1, argv+argc, back_inserter(args));
265
 
    
 
262
    for (int i=1; i<argc; i++) {
 
263
        if (0 == strcmp(argv[i], "-NSDocumentRevisionsDebugMode"))
 
264
            i++;
 
265
        else
 
266
            args.push_back(argv[i]);
 
267
    }
 
268
 
266
269
    // parse commandline arguments -- needs args
267
270
    AP ap;
268
271
    ap.parse();
274
277
        if (ap.show_help) usage();
275
278
        exit(0);
276
279
    }
277
 
    
 
280
 
278
281
    //
279
282
    if (ap.makepreview) {
280
283
        ap.force_window = true;
305
308
            }
306
309
        }
307
310
        setvbuf(stdout, NULL, _IOLBF, BUFSIZ);   // Line buffered
308
 
        
 
311
 
309
312
        newfp = std::freopen((userStdPath + "/Error.log").c_str(), "w", stderr);
310
313
        if ( newfp == NULL ) {  // This happens on NT
311
314
            newfp = fopen((userStdPath + "/Error.log").c_str(), "w");
317
320
    }
318
321
 
319
322
    // initialize logfile -- needs ap
320
 
    if (ap.do_log) 
 
323
    if (ap.do_log)
321
324
        enigma::Log.rdbuf(cout.rdbuf());
322
325
    else
323
326
        enigma::Log.rdbuf(::nullbuffer);
324
 
    
 
327
 
325
328
    // postponed system datapath logs
326
329
    Log << "Enigma " << getVersionInfo() << "\n";
327
 
    Log << "systemFS = \"" << systemFS->getDataPath() << "\"\n"; 
328
 
    Log << "docPath = \"" << docPath << "\"\n"; 
329
 
    Log << "l10nPath = \"" << l10nPath << "\"\n"; 
330
 
    Log << "prefPath = \"" << prefPath << "\"\n"; 
 
330
    Log << "systemFS = \"" << systemFS->getDataPath() << "\"\n";
 
331
    Log << "docPath = \"" << docPath << "\"\n";
 
332
    Log << "l10nPath = \"" << l10nPath << "\"\n";
 
333
    Log << "prefPath = \"" << prefPath << "\"\n";
331
334
 
332
335
    // initialize XML -- needs log, datapaths
333
336
    initXerces();
334
 
    
 
337
 
335
338
    // initialize LUA - Run initialization scripts
336
339
    lua_State *L = lua::GlobalState();
337
340
    lua::CheckedDoFile(L, app.systemFS, "startup.lua");
340
343
    if (!options::Load()) {
341
344
        fprintf(stderr, _("Error in configuration file.\n"));
342
345
        fprintf(stderr, "%s\n", lua::LastError (lua::GlobalState()).c_str());
343
 
    }     
 
346
    }
344
347
    prefs = PreferenceManager::instance();
345
 
    
 
348
 
346
349
    if (ap.force_window) {
347
350
        app.prefs->setProperty("FullScreen", false);
348
351
    }
353
356
 
354
357
    // initialize user data paths -- needs preferences, system datapaths
355
358
    initUserDatapaths();
356
 
    
 
359
 
357
360
    // set message language
358
361
    init_i18n();
359
 
    
 
362
 
360
363
    // initialize application state
361
364
    state = StateManager::instance();
362
365
 
386
389
    SDL_EnableUNICODE(1);
387
390
    const SDL_version* vi = SDL_Linked_Version();
388
391
    Log << ecl::strf("SDL Version: %u.%u.%u\n", vi->major, vi->minor, vi->patch);
389
 
    
 
392
 
390
393
    vi = TTF_Linked_Version();
391
394
    Log <<  ecl::strf("SDL_ttf Version: %u.%u.%u\n", vi->major, vi->minor, vi->patch);
392
395
    if(TTF_Init() == -1) {
398
401
    Log <<  ecl::strf("SDL_image Version: %u.%u.%u\n", vi->major, vi->minor, vi->patch);
399
402
#ifdef SDL_IMG_INIT
400
403
    int img_flags = IMG_INIT_PNG | IMG_INIT_JPG;
401
 
    if (IMG_Init(img_flags) & img_flags != img_flags) {
 
404
    if (IMG_Init(img_flags) & (img_flags != img_flags)) {
402
405
        fprintf(stderr, "Couldn't initialize SDL_image: %s\n", IMG_GetError());
403
406
        exit(1);
404
407
    }
423
426
        fprintf (stderr, "An error occurred while initializing Curl.\n");
424
427
        exit (1);
425
428
    }
426
 
    
 
429
 
427
430
    // ----- Initialize UDP network layer
428
431
    if (enet_initialize() != 0) {
429
432
        fprintf (stderr, "An error occurred while initializing ENet.\n");
452
455
    }
453
456
 
454
457
    lev::Proxy::countLevels();
455
 
    
 
458
 
456
459
    // ----- Initialize sound tables -- needs sound, oxyd, video (error messages!)
457
460
    sound::InitSoundSets();
458
461
 
459
462
    // ----- Initialize music -- needs application state
460
463
    sound::InitMusic();
461
 
    
 
464
 
462
465
#if MACOSX
463
466
    updateMac1_00();
464
467
#endif
466
469
    // initialize random
467
470
    enigma::Randomize(false);
468
471
    enigma::Randomize(true);
469
 
    
 
472
 
470
473
    //
471
474
    if (isMakePreviews) {
472
475
        app.state->setProperty("Difficulty", DIFFICULTY_HARD); // will not be saved
476
479
        std::string message = ecl::strf("Make %d previews on system path '%s'",
477
480
                size, systemAppDataPath.c_str());
478
481
        Log << message;
479
 
            
 
482
 
480
483
        Screen *scr = video::GetScreen();
481
484
        GC gc (scr->get_surface());
482
485
        Font *f = enigma::GetFont("menufont");
488
491
        vline(gc, 470, 280, 20);
489
492
        scr->update_all ();
490
493
        scr->flush_updates();
491
 
        
 
494
 
492
495
        int i = 0;
493
496
        for (int m=0; m<3; m++) {
494
497
            switch (m) {
495
498
                case 0 : video::SetThumbInfo(120, 78, ""); break;
496
499
                case 1 : video::SetThumbInfo(160, 104, "-160x104"); break;
497
500
                case 2 : video::SetThumbInfo(60, 39, "-60x39"); break;
498
 
            }        
 
501
            }
499
502
            for (it = proxies.begin(); it != proxies.end(); it++, i++) {
500
503
                Log << "Make preview " << (*it)->getId() << "\n";
501
504
                gui::LevelPreviewCache::makeSystemPreview(*it, systemAppDataPath);
504
507
                scr->flush_updates();
505
508
            }
506
509
        }
507
 
        Log << "Maske preview finished succesfully\n";
 
510
        Log << "Make preview finished successfully\n";
508
511
        return;
509
512
    }
510
 
    
 
513
 
511
514
    // initialize score -- needs random init
512
515
    lev::ScoreManager::instance();
513
516
}
517
520
    if (enigmaVersion >= ENIGMACOMPATIBITLITY)
518
521
        versionInfo = "v" PACKAGE_VERSION;
519
522
    else {
520
 
        versionInfo =  "v" PACKAGE_VERSION 
521
 
            " (development version - v" + 
 
523
        versionInfo =  "v" PACKAGE_VERSION
 
524
            " (development version - v" +
522
525
            ecl::strf("%.2f",ENIGMACOMPATIBITLITY) + " compatibility branch)";
523
526
    }
524
527
    return versionInfo;
535
538
    bool progDirExists = split_path(progCallPath, &progDir, &progName);
536
539
    std::string systemPath = SYSTEM_DATA_DIR; // substituted by configure.ac
537
540
    bool haveHome = (getenv("HOME") != 0);
 
541
 
 
542
 
538
543
#ifdef __MINGW32__
539
544
    // windows standard user specific application data directory path
540
545
    std::string winAppDataPath = ecl::ApplicationDataPath() + "/Enigma";
541
546
#endif
542
547
 
543
 
    // systemFS
544
 
    systemFS = new GameFS();
545
548
#ifdef __MINGW32__
546
549
    if (!progDirExists) {
547
550
        // filename only -- working dir should be on enigma as enigma
561
564
    // then chdir to ../Resources. The original SDL implementation chdirs to
562
565
    // "../../..", i.e. the directory the bundle is placed in. This breaks
563
566
    // the self-containedness.
564
 
        
 
567
 
565
568
    systemAppDataPath = progDir + "/../Resources/data";
566
 
    
 
569
 
567
570
#else
568
571
    // Unix -- we get our data path from the installation
569
572
    systemAppDataPath = systemPath;
570
573
#endif
 
574
 
 
575
    // systemFS
 
576
    systemFS = new GameFS();
571
577
    systemFS->append_dir(systemAppDataPath);
572
578
    if (!systemCmdDataPath.empty())
573
579
         systemFS->prepend_dir(systemCmdDataPath);
574
 
    
 
580
 
575
581
    // docPath
576
 
    docPath = DOCDIR;    // defined in src/Makefile.am 
 
582
    docPath = DOCDIR;    // defined in src/Makefile.am
577
583
#ifdef __MINGW32__
578
584
    if (progDirExists) {
579
585
        docPath = progDir;
581
587
#elif MACOSX
582
588
    docPath = progDir + "/../Resources/doc";
583
589
#endif
584
 
    
 
590
 
585
591
    // l10nPath
586
592
    l10nPath = LOCALEDIR;    // defined in src/Makefile.am
587
593
#ifdef __MINGW32__
643
649
        // If more than the error messages should be influenced we would
644
650
        // have to terminate and reinit after reading the user prefs.
645
651
        XMLPlatformUtils::Initialize();
646
 
        
 
652
 
647
653
        // Initialize transcoding service for XML <-> utf8
648
 
        XMLTransService::Codes initResult;        
 
654
        XMLTransService::Codes initResult;
649
655
        xmlUtf8Transcoder = XMLPlatformUtils::fgTransService->
650
 
                makeNewTranscoderFor(XMLRecognizer::UTF_8, initResult, 
651
 
                4096); // the block size is irrelevant for utf-8                  
 
656
                makeNewTranscoderFor(XMLRecognizer::UTF_8, initResult,
 
657
                4096); // the block size is irrelevant for utf-8
652
658
        if (initResult != XMLTransService::Ok) {
653
659
            fprintf(stderr, _("Error in XML initialization.\n"));
654
660
            exit(1);
655
661
        }
656
 
        
 
662
 
657
663
        static const XMLCh ls[] = { chLatin_L, chLatin_S, chNull };
658
664
        static const XMLCh core[] = { chLatin_C, chLatin_O,  chLatin_R, chLatin_E, chNull };
659
665
        domImplementationLS = (DOMImplementationLS*)
678
684
 
679
685
        domSer = domImplementationLS->createLSSerializer();
680
686
        config = domSer->getDomConfig();
681
 
        
 
687
 
682
688
        config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
683
689
        config->setParameter(XMLUni::fgDOMErrorHandler, domSerErrorHandler);
684
690
 
685
 
#else    
 
691
#else
686
692
        domParser = domImplementationLS->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
687
693
 
688
694
        domParser->setFeature(XMLUni::fgDOMNamespaces, true);
701
707
    catch (...) {
702
708
        fprintf(stderr, _("Error in XML initialization.\n"));
703
709
        exit(1);
704
 
    }     
705
 
}       
 
710
    }
 
711
}
706
712
 
707
713
void Application::initUserDatapaths() {
708
714
    // userPath
724
730
    } else {
725
731
        userPath = XMLtoLocal(Utf8ToXML(userPath.c_str()).x_str()).c_str();
726
732
    }
727
 
    Log << "userPath = \"" << userPath << "\"\n"; 
728
 
    
 
733
    Log << "userPath = \"" << userPath << "\"\n";
 
734
 
729
735
    // userImagePath
730
736
    userImagePath = prefs->getString("UserImagePath");
731
737
    if (userImagePath.empty()) {
732
738
#ifdef MACOSX
733
 
        userImagePath = userStdPathMac1_00;  // empty prefs user path is 1.00 std user path 
 
739
        userImagePath = userStdPathMac1_00;  // empty prefs user path is 1.00 std user path
734
740
#else
735
741
        userImagePath = userStdPath;
736
742
#endif
737
743
    } else {
738
744
        userImagePath = XMLtoLocal(Utf8ToXML(userImagePath.c_str()).x_str()).c_str();
739
745
    }
740
 
    Log << "userImagePath = \"" << userImagePath << "\"\n"; 
 
746
    Log << "userImagePath = \"" << userImagePath << "\"\n";
741
747
 
742
748
    // resourceFS
743
749
    resourceFS = new GameFS();
744
 
    resourceFS->append_dir(systemAppDataPath);    
 
750
    resourceFS->append_dir(systemAppDataPath);
745
751
#ifdef MACOSX
746
752
    // set user-visible data paths -- use it for resource paths
747
753
    NSSearchPathEnumerationState cur=NSStartSearchPathEnumeration(NSLibraryDirectory, NSAllDomainsMask);
753
759
    }
754
760
#endif
755
761
    if (!systemCmdDataPath.empty())
756
 
        resourceFS->prepend_dir(systemCmdDataPath);    
 
762
        resourceFS->prepend_dir(systemCmdDataPath);
757
763
    resourceFS->prepend_dir(userPath);
758
764
    if (userImagePath != userPath)
759
765
        resourceFS->prepend_dir(userImagePath);
760
 
    Log << "resourceFS = \"" << resourceFS->getDataPath() << "\"\n"; 
 
766
    Log << "resourceFS = \"" << resourceFS->getDataPath() << "\"\n";
761
767
 
762
768
    // create levels/auto, levels/cross, levels/legacy_dat on userPath
763
769
    if (!ecl::FolderExists(userPath + "/levels/auto"))
767
773
    if (!ecl::FolderExists(userPath + "/levels/externaldata"))
768
774
        ecl::FolderCreate (userPath + "/levels/externaldata");
769
775
    if (!ecl::FolderExists(userPath + "/levels/legacy_dat"))
770
 
        ecl::FolderCreate (userPath + "/levels/legacy_dat");   
 
776
        ecl::FolderCreate (userPath + "/levels/legacy_dat");
771
777
    if (!ecl::FolderExists(userPath + "/backup"))
772
 
        ecl::FolderCreate (userPath + "/backup");   
 
778
        ecl::FolderCreate (userPath + "/backup");
773
779
}
774
780
 
775
781
#ifdef MACOSX
776
782
void Application::updateMac1_00() {
777
 
    if (prefs->getInt("_MacUpdate1.00") == 0 && 
 
783
    if (prefs->getInt("_MacUpdate1.00") == 0 &&
778
784
            prefs->getString("UserPath").empty() &&
779
785
            prefs->getString("UserImagePath").empty()) {
780
786
        gui::ErrorMenu m(ecl::strf(N_("Mac OS X upgrade from Enigma 1.00\n\nThe default user data path has changed from\n  %s \n\nto the visible data path\n  %s \n\nIf ok Enigma will move your data to this new location.\nNote that you have to restart Enigma once for completion of this update."), userStdPathMac1_00.c_str(), userStdPath.c_str()),
786
792
            prefs->setProperty("_MacUpdate1.00", 0);
787
793
        } else {  // OK move now
788
794
            Log << "Mac update\n";
789
 
            // move 
 
795
            // move
790
796
            std::system(ecl::strf("mkdir '%s' && cd ~/.enigma && tar -cf - * | (cd '%s' && tar -xf -) && cd ~ && rm -rf ~/.enigma", userStdPath.c_str(), userStdPath.c_str()).c_str());
791
797
            setUserPath("");
792
798
            setUserImagePath("");
801
807
void Application::init_i18n()
802
808
{
803
809
    // Initialize the internationalization subsystem
804
 
    
 
810
 
805
811
    // priorities:
806
812
    // language: command-line --- user option --- system (environment)
807
813
    // defaultLanguage: command-line --- system (environment)
815
821
        if (app.language == "") {
816
822
            app.language = app.defaultLanguage;
817
823
        }
818
 
    }   
 
824
    }
819
825
 
820
826
#if defined(ENABLE_NLS)
821
827
 
832
838
 
833
839
void Application::setLanguage(std::string newLanguage)
834
840
{
835
 
    if (newLanguage == "") {
836
 
        language = defaultLanguage;
837
 
    }
838
 
    else {
839
 
        language = newLanguage;
840
 
    }
 
841
    language = newLanguage.empty() ? defaultLanguage : newLanguage;
841
842
    nls::SetMessageLocale(language);
842
843
}
843
844
 
845
846
    std::string prefUserPath = (newPath == userStdPath) ? "" : newPath;
846
847
    if ((prefUserPath.empty() && userPath != userStdPath) || (!prefUserPath.empty() && prefUserPath != userPath)) {
847
848
        // set the new userPath - used for saves
848
 
        if (prefUserPath.empty())    
 
849
        if (prefUserPath.empty())
849
850
            userPath = userStdPath;
850
851
        else
851
852
            userPath = prefUserPath;
852
 
        
 
853
 
853
854
        // load all resources primarily from the new path but keep the old user path
854
855
        // because the user could not yet copy his user data to the new location
855
856
        resourceFS->prepend_dir(userPath);
856
 
        
 
857
 
857
858
        // set the new path as the users preference - the standard path is saved as ""
858
859
#ifdef MACOSX
859
860
        // 1.00 uses "" as "~/.enigma" - we have to store the complete path
867
868
    std::string prefUserImagePath = (newPath == userStdPath) ? "" : newPath;
868
869
    if ((prefUserImagePath.empty() && userImagePath != userStdPath) || (!prefUserImagePath.empty() && prefUserImagePath != userImagePath)) {
869
870
        // set the new userImagePath - used for saves
870
 
        if (prefUserImagePath.empty())    
 
871
        if (prefUserImagePath.empty())
871
872
            userImagePath = userStdPath;
872
873
        else
873
874
            userImagePath = prefUserImagePath;
874
 
                
 
875
 
875
876
        // load all resources primarily from the new path but keep the old user path
876
877
        // because the user could not yet copy his user data to the new location
877
878
        if (userImagePath != userPath)
888
889
 
889
890
/* -------------------- Functions -------------------- */
890
891
 
891
 
void Application::shutdown() 
 
892
void Application::shutdown()
892
893
{
893
894
    oxyd::Shutdown();
894
895
    enigma::ShutdownWorld();
895
896
    display::Shutdown();
896
897
    if (!isMakePreviews) { // avoid saves on preview generation
897
898
        lev::RatingManager::instance()->save();
898
 
        if (lev::PersistentIndex::historyIndex != NULL) 
 
899
        if (lev::PersistentIndex::historyIndex != NULL)
899
900
            lev::PersistentIndex::historyIndex->save();
900
901
        lev::ScoreManager::instance()->shutdown();
901
902
        app.state->shutdown();
918
919
    delete ::nullbuffer;
919
920
}
920
921
 
921
 
int main(int argc, char** argv) 
 
922
int main(int argc, char **argv)
922
923
{
923
924
    try {
924
925
        app.init(argc,argv);