Add a screen rotation class (time multiplexing).
[ccbs] / bigscreen / rotatescreen.cpp
1 #include <cstring>
2 #include "rotatescreen.h"
3
4 RotateScreen::RotateScreen()
5         : valid(false), current_screen(0)
6 {
7 }
8
9 RotateScreen::~RotateScreen()
10 {
11 }
12
13 bool RotateScreen::check_invalidated()
14 {
15         if (!valid)
16                 return true;
17
18         if (needs_update())
19                 return true;
20         
21         for (unsigned i = 0; i < subscreens.size(); ++i) {
22                 if (subscreens[i].screen->check_invalidated())
23                         return true;
24         }
25
26         return false;
27 }
28
29 void RotateScreen::draw(unsigned char *buf)
30 {
31         bool force = false;
32         
33         // push any invalidated screen first (for now)
34         for (unsigned i = 0; i < subscreens.size(); ++i) {
35                 if (subscreens[i].screen->check_invalidated()) {
36                         current_screen = i;
37                         force = true;
38                 }
39         }
40
41         // check if we want to go to the next screen
42         if (valid && !force && needs_update()) {
43                 current_screen = (current_screen + 1) % subscreens.size();
44                 gettimeofday(&last_update, NULL);
45         }
46
47         if (subscreens[current_screen].screen->check_invalidated())
48                 subscreens[current_screen].screen->draw(subscreens[current_screen].buf);
49         
50         memcpy(buf, subscreens[current_screen].buf, 800 * 600 * 4);
51
52         if (!valid) {
53                 valid = true;
54                 gettimeofday(&last_update, NULL);
55         }
56 }
57         
58 // note: makes no sense if valid=false!
59 bool RotateScreen::needs_update()
60 {
61         struct timeval now;
62         gettimeofday(&now, NULL);
63
64         double since = double(now.tv_sec - last_update.tv_sec) +
65                 double(now.tv_usec - last_update.tv_usec) * 1.0e-6;
66
67         return (since >= 10.0);
68 }
69
70 void RotateScreen::add_screen(GenericScreen *screen)
71 {
72         Subscreen ss;
73         ss.buf = new unsigned char[800 * 600 * 4];
74         ss.screen = screen;
75
76         subscreens.push_back(ss);
77 }
78