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