]> git.tdb.fi Git - libs/demoscene.git/blob - source/demo.cpp
Make it possible for Stages to add things to the Demo
[libs/demoscene.git] / source / demo.cpp
1 #include <msp/time/utils.h>
2 #include "demo.h"
3 #include "stage.h"
4
5 using namespace std;
6 using namespace Msp;
7
8 Demo::Demo(Graphics::Window &window, Graphics::GLContext &gl_ctx, DataFile::Collection &r):
9         resources(r),
10         view(window, gl_ctx),
11         anim_action(anim_player),
12         music_source(0),
13         streamer(0),
14         music_io(0),
15         music_decoder(0)
16 {
17         things["window"] = static_cast<GL::View *>(&view);
18
19         sequencer.add_static_action(anim_action);
20         sequencer.signal_finished.connect(signal_finished);
21 }
22
23 Demo::~Demo()
24 {
25         delete streamer;
26         delete music_decoder;
27         delete music_io;
28         delete music_source;
29 }
30
31 void Demo::add_stage(const std::string &name, Stage &stage)
32 {
33         things[name] = &stage;
34         stage.add_things(things, name+".");
35 }
36
37 void Demo::set_fixed_framerate(float fps)
38 {
39         frame_interval = Time::sec/fps;
40 }
41
42 void Demo::enable_music()
43 {
44         if(!music_source)
45                 music_source = new AL::Source;
46         if(!streamer)
47                 streamer = new AL::Streamer(*music_source);
48 }
49
50 void Demo::play_music(const string &fn)
51 {
52         if(!streamer)
53                 return;
54
55         streamer->stop();
56         delete music_decoder;
57         delete music_io;
58         music_io = resources.open_raw(fn);
59         music_decoder = AL::SoundDecoder::open_io(*music_io);
60         float beat = sequencer.get_current_beat();
61         if(beat)
62         {
63                 float time = beat*60/sequencer.get_beats_per_minute();
64                 unsigned bytes_per_sec = music_decoder->get_frequency()*get_unit_size(music_decoder->get_format());
65                 music_decoder->seek(time*bytes_per_sec);
66         }
67         streamer->play(*music_decoder);
68 }
69
70 void Demo::tick()
71 {
72         Time::TimeStamp t = Time::now();
73         Time::TimeDelta dt = (last_tick ? frame_interval ? frame_interval : t-last_tick : Time::zero);
74         last_tick = t;
75
76         if(frame_interval)
77                 next_frame = t+frame_interval;
78
79         sequencer.tick(dt);
80         if(streamer)
81                 streamer->tick();
82         view.render();
83 }
84
85 void Demo::seek(const Time::TimeDelta &pos)
86 {
87         sequencer.seek(pos*sequencer.get_beats_per_minute()/Time::min);
88 }
89
90
91 Demo::AnimationAction::AnimationAction(GL::AnimationPlayer &p):
92         player(p)
93 { }
94
95 void Demo::AnimationAction::tick(float, float d)
96 {
97         player.tick(d*Time::sec);
98 }