+#include <cstring>
+#include "rotatescreen.h"
+
+RotateScreen::RotateScreen()
+ : valid(false), current_screen(0)
+{
+}
+
+RotateScreen::~RotateScreen()
+{
+}
+
+bool RotateScreen::check_invalidated()
+{
+ if (!valid)
+ return true;
+
+ if (needs_update())
+ return true;
+
+ for (unsigned i = 0; i < subscreens.size(); ++i) {
+ if (subscreens[i].screen->check_invalidated())
+ return true;
+ }
+
+ return false;
+}
+
+void RotateScreen::draw(unsigned char *buf)
+{
+ bool force = false;
+
+ // push any invalidated screen first (for now)
+ for (unsigned i = 0; i < subscreens.size(); ++i) {
+ if (subscreens[i].screen->check_invalidated()) {
+ current_screen = i;
+ force = true;
+ }
+ }
+
+ // check if we want to go to the next screen
+ if (valid && !force && needs_update()) {
+ current_screen = (current_screen + 1) % subscreens.size();
+ gettimeofday(&last_update, NULL);
+ }
+
+ if (subscreens[current_screen].screen->check_invalidated())
+ subscreens[current_screen].screen->draw(subscreens[current_screen].buf);
+
+ memcpy(buf, subscreens[current_screen].buf, 800 * 600 * 4);
+
+ if (!valid) {
+ valid = true;
+ gettimeofday(&last_update, NULL);
+ }
+}
+
+// note: makes no sense if valid=false!
+bool RotateScreen::needs_update()
+{
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ double since = double(now.tv_sec - last_update.tv_sec) +
+ double(now.tv_usec - last_update.tv_usec) * 1.0e-6;
+
+ return (since >= 10.0);
+}
+
+void RotateScreen::add_screen(GenericScreen *screen)
+{
+ Subscreen ss;
+ ss.buf = new unsigned char[800 * 600 * 4];
+ ss.screen = screen;
+
+ subscreens.push_back(ss);
+}
+