~ubuntu-branches/ubuntu/trusty/enigma/trusty-proposed

« back to all changes in this revision

Viewing changes to src/MusicManager.cc

  • Committer: Package Import Robot
  • Author(s): Erich Schubert
  • Date: 2013-04-06 14:54:02 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130406145402-jgjrtk7hac8gtvza
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:
22
22
#include "MusicManager.hh"
23
23
#include "SoundEngine.hh"
24
24
#include "main.hh"
 
25
#include "lev/RatingManager.hh"
 
26
#include "lev/Index.hh"
25
27
 
26
28
#include "SDL.h"
27
29
#include "SDL_mixer.h"
51
53
 
52
54
void sound::SetInGameMusicActive(bool active)
53
55
{
54
 
    // TODO!
55
 
    if (active)
56
 
        sound::PlayMusic(options::GetString("LevelMusicFile"));
57
 
    else
58
 
        sound::StopMusic();
 
56
    MusicManager::instance()->setInGameMusicActive(active);
59
57
}
60
58
 
61
59
void sound::MusicTick(double dtime)
69
67
    MusicManager::instance()->init();
70
68
}
71
69
 
72
 
void sound::DefineMusicSingle(std::string title, std::string filename) {
 
70
void sound::DefineMusicSingle(std::string title, std::string filename,
 
71
        float affinity_intelligence, float affinity_dexterity, float affinity_patience,
 
72
        float affinity_knowledge, float affinity_speed)
 
73
{
73
74
    if(filename == "") {
74
75
        Log << "Warning: Tried to define music single '" << title
75
76
            << "' without file name. Skipped.\n";
76
77
        return;
77
78
    }
78
 
    MusicManager::instance()->defineMusicSingle(title, filename);
 
79
    MusicManager::instance()->defineMusicSingle(title, filename,
 
80
        affinity_intelligence, affinity_dexterity, affinity_patience,
 
81
        affinity_knowledge, affinity_speed);
79
82
}
80
83
 
81
84
/* -------------------- Sound option helpers -------------------- */
99
102
{
100
103
    std::string music_queue = MusicManager::instance()->getMusicQueueByPosition(value);
101
104
    app.state->setProperty("MenuMusicQueue", music_queue);
102
 
    MusicManager::instance()->setActiveMusicQueue(music_queue);
 
105
    MusicManager::instance()->setMenuMusicQueue(music_queue);
103
106
}
104
107
 
105
108
std::string sound::GetOptionMenuMusicText(int value)
120
123
 
121
124
MusicManager::MusicManager()
122
125
: music_singles(), music_queues(), active_music_queue_title(""),
123
 
  wait_length(-1), music_context(MUSIC_NONE), is_waiting(false)
124
 
{}    
 
126
  ingame_music_queue_title(""), menu_music_queue_title(""),
 
127
  wait_length(-1), music_context(MUSIC_NONE), is_waiting(false),
 
128
  ingame_music_active(false)
 
129
{}
125
130
 
126
131
void MusicManager::tick(double dtime)
127
132
{
138
143
            }        
139
144
        } else {
140
145
            // Music has really ended or not even begun.
141
 
            switch(MusicManager::instance()->getMusicContext()) {
 
146
            switch(getMusicContext()) {
142
147
                case MUSIC_NONE:
143
148
                    break;
 
149
                case MUSIC_GAME:
 
150
                    if(ingame_music_active)
 
151
                        music_queues[active_music_queue_title].onMusicEnded(false);
 
152
                    break;
144
153
                case MUSIC_MENU:
145
154
                    if(active_music_queue_title != "")
146
155
                        music_queues[active_music_queue_title].onMusicEnded(false);
149
158
                    // Fadeout ended while level is still loading.
150
159
                    // Just wait until load is complete.
151
160
                    break;
152
 
                case MUSIC_GAME:
153
 
                    // TODO
154
 
                    //if (options::GetBool("InGameMusic")) {
155
 
                    //}
156
 
                    break;
157
161
                default:
158
162
                    Log << "Error: getMusicContext() returns an invalid type. Will ignore this.\n";
159
163
            }
168
172
 
169
173
    switch(new_context) {
170
174
        case MUSIC_MENU:
171
 
            sound::FadeoutMusic();
172
 
            stopWaiting();
173
 
            if(active_music_queue_title != "") {
174
 
                // onMusicEnded(true) means: force music, no waiting!
175
 
                music_queues[active_music_queue_title].onMusicEnded(true);
176
 
            }
 
175
            //sound::FadeoutMusic();
 
176
            //stopWaiting();
 
177
            //if(active_music_queue_title != "") {
 
178
            //    // onMusicEnded(true) means: force music, no waiting!
 
179
            //    music_queues[active_music_queue_title].onMusicEnded(true);
 
180
            //}
 
181
            Log << "Switching to menu music.\n";
177
182
            music_context = new_context;
 
183
            setActiveMusicQueue(getMenuMusicQueueTitle());
178
184
            break;
179
185
        case MUSIC_LEVEL_LOADING:
180
 
            sound::FadeoutMusic(false);
181
 
            stopWaiting();
182
 
            music_context = new_context;
 
186
            Log << "Switching to level load music.\n";
 
187
            if(music_context == MUSIC_GAME) {
 
188
                // Switching from one level to another.
 
189
                music_context = new_context;
 
190
            } else {
 
191
                // Switching from menu to level, stop menu music.
 
192
                music_queues[active_music_queue_title].calculate_level_points();
 
193
                music_context = new_context;                
 
194
                setActiveMusicQueue(getInGameMusicQueueTitle());
 
195
            }
183
196
            break;
184
 
        case MUSIC_GAME:        
185
 
            sound::FadeoutMusic(true);
186
 
            stopWaiting();
 
197
        case MUSIC_GAME:
 
198
            Log << "Switching to level music.\n";
 
199
            // TODO: Stop music if current music is not suitable.
 
200
            music_queues[active_music_queue_title].calculate_level_points();
187
201
            music_context = new_context;
 
202
            //sound::FadeoutMusic();
 
203
            setActiveMusicQueue(getInGameMusicQueueTitle());
188
204
            // We do not force music here, but leave it to "tick" to handle.
189
205
            break;
190
206
        case MUSIC_NONE:
 
207
            Log << "Switching to no music.\n";
191
208
            sound::FadeoutMusic(false);
192
209
            break;
193
210
    }    
197
214
{
198
215
    // TODO: This is only temporary. Information will come 
199
216
    // from an xml file later.
 
217
    
 
218
    // Menu Music
200
219
    music_singles["Esprit"] =
201
220
        MusicSingle("Esprit", "music/menu/esprit.ogg");
 
221
    //music_singles["Pentagonal Dreams"] =
 
222
    //    MusicSingle("Pentagonal Dreams", "music/menu/pentagonal_dreams.s3m");
 
223
    
 
224
    // Level Music
 
225
    music_singles["Across The Ice"] =
 
226
        MusicSingle("Across The Ice", "music/game/across_the_ice.ogg", 0, 0.5, 0, 0, 0.5);
 
227
    music_singles["In Space"] =
 
228
        MusicSingle("In Space", "music/game/in_space.ogg", 0.3, 0, 0.4, 0, -0.3);
 
229
    music_singles["Meditation"] =
 
230
        MusicSingle("Meditation", "music/game/meditation.ogg", 0.4, 0.2, 0.4, 0, 0);
 
231
    music_singles["On The Water"] =
 
232
        MusicSingle("On The Water", "music/game/on_the_water.ogg", 0.2, 0.2, 0.2, 0.2, 0.4);
 
233
    music_singles["Puzzle"] =
 
234
        MusicSingle("Puzzle", "music/game/puzzle.ogg", 0.4, 0, 0.3, 0, 0.3);
 
235
    music_singles["Skull Stones"] =
 
236
        MusicSingle("Skull Stones", "music/game/skull_stones.ogg", 0, 0.5, -0.5, 0, 0);
 
237
    music_singles["Swamp"] =
 
238
        MusicSingle("Swamp", "music/game/swamp.ogg", 0.4, 0.1, -0.3, 0, 0.2);
 
239
 
 
240
    // Menu and Level Music
202
241
    music_singles["Enigma Rag"] =
203
 
        MusicSingle("Enigma Rag", "music/menu/enigma_rag.ogg");
204
 
    music_singles["Pentagonal Dreams"] =
205
 
        MusicSingle("Pentagonal Dreams", "music/menu/pentagonal_dreams.s3m");
 
242
        MusicSingle("Enigma Rag", "music/menu/enigma_rag.ogg", 0.4, -0.2, 0, 0, 0.4);
206
243
 
207
 
    music_queues["Default"] = MusicQueue("Default", 0);
 
244
    // Menu Music Queues
 
245
    music_queues["Default"] = MusicQueue("Default", MUSICQUEUE_NEXT, 0);
208
246
    music_queues["Default"].appendSingle("Esprit", false);
209
247
    music_queues["Default"].appendSingle("Esprit", false);
210
248
    music_queues["Default"].appendSingleThenWait("Esprit", true, 8.0);
211
249
    music_queues["Default"].appendSingleThenWait("Enigma Rag", true, 8.0);
212
 
    music_queues["Default"].appendSingleThenWait("Pentagonal Dreams", true, 8.0);
 
250
    //music_queues["Default"].appendSingleThenWait("Pentagonal Dreams", true, 8.0);
213
251
 
214
 
    music_queues["Esprit"] = MusicQueue("Esprit", 1);
 
252
    music_queues["Esprit"] = MusicQueue("Esprit", MUSICQUEUE_NEXT, 1);
215
253
    music_queues["Esprit"].appendSingle("Esprit", false);
216
254
 
217
 
    music_queues["Enigma Rag"] = MusicQueue("Enigma Rag", 2);
 
255
    music_queues["Enigma Rag"] = MusicQueue("Enigma Rag", MUSICQUEUE_NEXT, 2);
218
256
    music_queues["Enigma Rag"].appendSingleThenWait("Enigma Rag", false, 8.0);
219
257
 
220
 
    music_queues["Pentagonal Dreams"] = MusicQueue("Pentagonal Dreams", 3);
221
 
    music_queues["Pentagonal Dreams"].appendSingle("Pentagonal Dreams", true);
 
258
    //music_queues["Pentagonal Dreams"] = MusicQueue("Pentagonal Dreams", MUSICQUEUE_NEXT, 3);
 
259
    //music_queues["Pentagonal Dreams"].appendSingle("Pentagonal Dreams", true);
222
260
 
223
261
    active_music_queue_title = app.state->getString("MenuMusicQueue");
224
262
    // Set the default menu music queue, if saved queue doesn't exist.
229
267
        active_music_queue_title = "Default";
230
268
        app.state->setProperty("MenuMusicQueue", active_music_queue_title);
231
269
    }
 
270
 
 
271
    // Level Music Queue
 
272
    music_queues["In Game"] = MusicQueue("In Game", MUSICQUEUE_LEVEL, 4);
 
273
    music_queues["In Game"].appendSingleThenWait("Across The Ice", true, 3.0);
 
274
    music_queues["In Game"].appendSingleThenWait("In Space", true, 3.0);
 
275
    music_queues["In Game"].appendSingleThenWait("Meditation", true, 3.0);
 
276
    music_queues["In Game"].appendSingleThenWait("On The Water", true, 3.0);
 
277
    music_queues["In Game"].appendSingleThenWait("Puzzle", true, 3.0);
 
278
    music_queues["In Game"].appendSingleThenWait("Skull Stones", true, 3.0);
 
279
    music_queues["In Game"].appendSingleThenWait("Swamp", true, 3.0);
 
280
    music_queues["In Game"].appendSingleThenWait("Enigma Rag", true, 3.0);
 
281
    
 
282
    menu_music_queue_title = app.state->getString("MenuMusicQueue");
 
283
    // Set the default menu music queue, if saved queue doesn't exist.
 
284
    if(music_queues.find(menu_music_queue_title) == music_queues.end())
 
285
    {
 
286
        Log << "Warning: Did not find specified menu music queue '"
 
287
            << menu_music_queue_title << "', will switch to default.\n";
 
288
        menu_music_queue_title = "Default";
 
289
        app.state->setProperty("MenuMusicQueue", menu_music_queue_title);
 
290
    }
 
291
    ingame_music_active = app.prefs->getBool("InGameMusic");
 
292
    ingame_music_queue_title = "In Game";   
232
293
    
233
294
    // setMusicContext will set active_music_queue_title as well;
234
295
    // after this, tick will start the music.
236
297
    tick(-1);
237
298
}
238
299
 
239
 
bool MusicManager::defineMusicSingle(std::string title, std::string filename)
 
300
bool MusicManager::defineMusicSingle(std::string title, std::string filename,
 
301
            float affinity_intelligence, float affinity_dexterity, float affinity_patience,
 
302
            float affinity_knowledge, float affinity_speed)
240
303
{
241
 
    music_singles[title] = MusicSingle(title, filename);
 
304
    music_singles[title] = MusicSingle(title, filename, affinity_intelligence,
 
305
        affinity_dexterity, affinity_patience, affinity_knowledge, affinity_speed);
242
306
    Log << "Added music single '" << title << "'.\n";
243
307
    return true;
244
308
}
268
332
bool MusicManager::setActiveMusicQueue(std::string music_queue_title)
269
333
{
270
334
    if (music_queue_title == "") {
271
 
        Log << "Warning: Tried to choose empty music queue title as menu music queue.\n";
 
335
        Log << "Warning: Tried to choose empty music queue title as active music queue.\n";
272
336
        return false;
273
337
    }
274
338
    if (music_queue_title == getActiveMusicQueueTitle()) {
280
344
    if (active_music_queue_title != "")
281
345
        music_queues[active_music_queue_title].leave();
282
346
    // Switch to new queue if possible.
283
 
    if (music_queues[music_queue_title].next()) {
284
 
        active_music_queue_title = music_queue_title;
285
 
        Log << "Switched to menu music queue '" << music_queue_title << "'.\n";
286
 
        return true;
287
 
    } else {
288
 
        active_music_queue_title = "";
289
 
        Log << "Warning: Problems loading menu music queue '" << music_queue_title << "'.\n";
290
 
        return false;
291
 
    }
 
347
    stopWaiting();
 
348
    active_music_queue_title = music_queue_title;
 
349
    Log << "Switched to music queue '" << music_queue_title << "'.\n";
 
350
    return true;
 
351
    // We leave it to tick to start the new queue.
 
352
}
 
353
 
 
354
bool MusicManager::setMenuMusicQueue(std::string music_queue_title)
 
355
{
 
356
    if (music_queue_title == "") {
 
357
        Log << "Warning: Tried to choose empty music queue title as menu music queue.\n";
 
358
        return false;
 
359
    }
 
360
    if (menu_music_queue_title == music_queue_title)
 
361
        return true;
 
362
    menu_music_queue_title = music_queue_title;
 
363
    if(getMusicContext() == MUSIC_MENU)
 
364
        return setActiveMusicQueue(music_queue_title);
 
365
    return true;
 
366
}
 
367
 
 
368
bool MusicManager::setInGameMusicQueue(std::string music_queue_title)
 
369
{
 
370
    if (music_queue_title == "") {
 
371
        Log << "Warning: Tried to choose empty music queue title as in-game music queue.\n";
 
372
        return false;
 
373
    }
 
374
    if (ingame_music_queue_title == music_queue_title)
 
375
        return true;
 
376
    ingame_music_queue_title = music_queue_title;
 
377
    if(getMusicContext() == MUSIC_GAME)
 
378
        return setActiveMusicQueue(music_queue_title);
 
379
    return true;
292
380
}
293
381
 
294
382
std::string MusicManager::getMusicQueueByPosition(int button_position)
317
405
        return "";
318
406
}
319
407
 
320
 
 
321
 
/* -------------------- MusicSingle -------------------- */
 
408
void MusicManager::setInGameMusicActive(bool active)
 
409
{
 
410
    ingame_music_active = active;
 
411
    if ((getMusicContext() == MUSIC_GAME) && (!ingame_music_active))
 
412
    {
 
413
        sound::FadeoutMusic();
 
414
        if (active_music_queue_title != "")
 
415
            music_queues[active_music_queue_title].leave();
 
416
    }
 
417
}
 
418
 
 
419
MusicSingle MusicManager::getMusicSingle(std::string title)
 
420
{
 
421
    if(music_singles.find(title) != music_singles.end())
 
422
        return music_singles[title];
 
423
    else
 
424
    {
 
425
        Log << "Warning: Did not find music single " << title << ".\n";
 
426
        return MusicSingle();
 
427
    }
 
428
}
 
429
 
 
430
/* -------------------- Music Single -------------------- */
322
431
 
323
432
bool MusicSingle::start()
324
433
{
329
438
    return false;
330
439
}
331
440
 
 
441
float MusicSingle::affinity(float lev_int, float lev_dex, float lev_pat,
 
442
                            float lev_kno, float lev_spe)
 
443
{
 
444
    return   (affinity_intelligence * lev_int)
 
445
           + (affinity_dexterity * lev_dex)
 
446
           + (affinity_patience * lev_pat)
 
447
           + (affinity_knowledge * lev_kno)
 
448
           + (affinity_speed * lev_spe);
 
449
}
 
450
 
 
451
 
332
452
/* -------------------- Music Queue -------------------- */
333
453
 
334
454
std::string MusicQueue::getCurrentMusicTitle()
350
470
    //       queue should be read.
351
471
    new_entry.wait_length = -1;
352
472
    new_entry.no_music = false;
 
473
    new_entry.points_transient = 0;
 
474
    new_entry.points_level = 0;
 
475
    new_entry.points_total = 0;
353
476
    queue_entry.push_back(new_entry);
354
477
}
355
478
 
367
490
    new_entry.fadeout_on_end = false;
368
491
    new_entry.wait_length = seconds;
369
492
    new_entry.no_music = true;
 
493
    new_entry.points_transient = 0;
 
494
    new_entry.points_level = 0;
 
495
    new_entry.points_total = 0;
370
496
    queue_entry.push_back(new_entry);
371
497
}
372
498
 
379
505
    // "next()" will also take care of empty queues.
380
506
}
381
507
 
 
508
void MusicQueue::calculate_level_points()
 
509
{
 
510
    lev::RatingManager *theRatingMgr = lev::RatingManager::instance();
 
511
    lev::Proxy *currentLevel = (lev::Index::getCurrentIndex())->getCurrent();
 
512
    MusicManager *theMusicMgr = MusicManager::instance();
 
513
    float currentInt = theRatingMgr->getIntelligence(currentLevel);
 
514
    float currentDex = theRatingMgr->getDexterity(currentLevel);
 
515
    float currentPat = theRatingMgr->getPatience(currentLevel);
 
516
    float currentKno = theRatingMgr->getKnowledge(currentLevel);
 
517
    float currentSpe = theRatingMgr->getSpeed(currentLevel);
 
518
    // If the requested level does not exist, theRatingMgr will
 
519
    // return 0 instead. We shift ratings such that 2.8 is seen as 0.
 
520
    // Special handling for knowledge == 6 (set to 0).
 
521
    //Log << currentInt << "/" << currentDex << "/" << currentPat << "/" <<
 
522
    // currentKno << "/" << currentSpe << "\n";
 
523
    currentInt = (currentInt == 0) ? 0 : (currentInt - 2.8);
 
524
    currentDex = (currentDex == 0) ? 0 : (currentDex - 2.8);
 
525
    currentPat = (currentPat == 0) ? 0 : (currentPat - 2.8);
 
526
    currentKno = ((currentKno == 0) || (currentKno == 6)) ? 0 : (currentKno - 2.8);
 
527
    currentSpe = (currentSpe == 0) ? 0 : (currentSpe - 2.8);
 
528
    //Log << currentInt << "/" << currentDex << "/" << currentPat << "/" <<
 
529
    // currentKno << "/" << currentSpe << "\n";
 
530
    for(int j = 0; j < queue_entry.size(); j++)
 
531
        if(queue_entry[j].type == MUSICQUEUE_SINGLE)
 
532
        {
 
533
            std::string title = queue_entry[j].title;
 
534
            queue_entry[j].points_level =
 
535
                (theMusicMgr->getMusicSingle(title)).affinity(
 
536
                currentInt, currentDex, currentPat, currentKno, currentSpe);
 
537
            //Log << title << ": " << queue_entry[j].points_level << "\n";
 
538
        }
 
539
}
 
540
 
382
541
bool MusicQueue::next(bool force_music)
383
542
{
384
543
    if(defunc)
396
555
            sound::FadeoutMusic();
397
556
    }
398
557
 
399
 
    // Jump to next position in queue.
400
 
    // TODO: Add random
401
 
    current_position_in_queue = (current_position_in_queue + 1) % queue_entry.size();
402
 
 
 
558
    int new_position = (current_position_in_queue >= 0) ? current_position_in_queue : 0;
 
559
    switch(shuffle_type) {
 
560
        case MUSICQUEUE_NEXT:
 
561
            // Jump to next position in queue.
 
562
            new_position = (current_position_in_queue + 1) % queue_entry.size();
 
563
            break;
 
564
        case MUSICQUEUE_RANDOM:
 
565
            // Jump to a random position in queue other than the current.
 
566
            if(queue_entry.size() < 2)
 
567
                break; // Don't change current_position.
 
568
            while (new_position == current_position_in_queue)
 
569
                new_position = IntegerRand(0, queue_entry.size() - 1, false);
 
570
            break;
 
571
        case MUSICQUEUE_LEVEL:
 
572
            // Calculate the optimal single (or maybe silence phase).
 
573
            if(current_position_in_queue >= 0)
 
574
                queue_entry[current_position_in_queue].points_transient += -10;
 
575
            for(int j = 0; j < queue_entry.size(); j++)
 
576
            {
 
577
                queue_entry[j].points_transient = queue_entry[j].points_transient / 2.0;
 
578
                queue_entry[j].points_total = queue_entry[j].points_transient
 
579
                    + queue_entry[j].points_level + IntegerRand(0, 300, false) / 1000.0;
 
580
                Log << j << ": " << queue_entry[j].title << ": " << queue_entry[j].points_level
 
581
                    << " + " << queue_entry[j].points_transient << " -> " <<
 
582
                    queue_entry[j].points_total << "\n";
 
583
            }
 
584
            float best_value = queue_entry[new_position].points_total;
 
585
            for(int j = 0; j < queue_entry.size(); j++)
 
586
                if (queue_entry[j].points_total >= best_value)
 
587
                {
 
588
                    best_value = queue_entry[j].points_total;
 
589
                    new_position = j;
 
590
                }
 
591
            Log << "Chose " << queue_entry[new_position].title << "\n";
 
592
            break;
 
593
    }
 
594
    current_position_in_queue = new_position;
 
595
        
403
596
    MusicQueueEntry current_entry = queue_entry[current_position_in_queue];
404
597
    bool success = false;
405
598
    switch(current_entry.type) {