From 865e85b2e5da68f6bf0b907d239f2277579382a6 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 20 Feb 2005 01:26:14 +0000 Subject: [PATCH] Add a screen rotation class (time multiplexing). --- bigscreen/Makefile | 2 +- bigscreen/ccbs_bigscreen.cpp | 9 ++++- bigscreen/rotatescreen.cpp | 78 ++++++++++++++++++++++++++++++++++++ bigscreen/rotatescreen.h | 39 ++++++++++++++++++ 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 bigscreen/rotatescreen.cpp create mode 100644 bigscreen/rotatescreen.h diff --git a/bigscreen/Makefile b/bigscreen/Makefile index 2afcd30..42b031f 100644 --- a/bigscreen/Makefile +++ b/bigscreen/Makefile @@ -4,7 +4,7 @@ CPPFLAGS=-I/usr/include/postgresql $(shell freetype-config --cflags) -Itinyptc/ CXXFLAGS=-g -Wall LDFLAGS=-L/usr/X11R6/lib LIBS=$(shell freetype-config --libs) $(shell libpq3-config) -lpqxx tinyptc/libtinyptc.a -lX11 -CCBS_BIGSCREEN_OBJS=ccbs_bigscreen.o flagtrigger.o widestring.o fetch_current_tournament.o fetch_list_of_active_groups.o fetch_max_score_for_song.o fetch_max_score_for_player.o fetch_group.o fonts.o groupscreen.o splitscreen.o screen.o +CCBS_BIGSCREEN_OBJS=ccbs_bigscreen.o flagtrigger.o widestring.o fetch_current_tournament.o fetch_list_of_active_groups.o fetch_max_score_for_song.o fetch_max_score_for_player.o fetch_group.o fonts.o groupscreen.o splitscreen.o rotatescreen.o screen.o all: ccbs-bigscreen diff --git a/bigscreen/ccbs_bigscreen.cpp b/bigscreen/ccbs_bigscreen.cpp index 2114093..829f84d 100644 --- a/bigscreen/ccbs_bigscreen.cpp +++ b/bigscreen/ccbs_bigscreen.cpp @@ -12,11 +12,13 @@ #include "fonts.h" #include "groupscreen.h" #include "splitscreen.h" +#include "rotatescreen.h" Tournament active_tournament; std::vector active_groups; std::vector screens; -SplitScreen *mainscreen = NULL; +//SplitScreen *mainscreen = NULL; +RotateScreen *mainscreen = NULL; unsigned char framebuf[800 * 600 * 4], screenbuf[800 * 600 * 4]; void init(pqxx::connection &conn) @@ -31,6 +33,8 @@ void init(pqxx::connection &conn) conn.perform(FetchCurrentTournament(&active_tournament)); conn.perform(FetchListOfActiveGroups(&active_groups)); + mainscreen = new RotateScreen(); + if (active_tournament.id == -1) { std::fprintf(stderr, "No active tournament\n"); } else { @@ -41,6 +45,7 @@ void init(pqxx::connection &conn) i->tournament, i->round, i->parallel); screens.push_back(new GroupScreen(conn, i->tournament, i->round, i->parallel)); + mainscreen->add_screen(screens[screens.size() - 1]); } } @@ -50,7 +55,7 @@ void init(pqxx::connection &conn) screens.push_back(NULL); screens.push_back(NULL); - mainscreen = new SplitScreen(screens[0], screens[1], screens[2], screens[3]); + //mainscreen = new SplitScreen(screens[0], screens[1], screens[2], screens[3]); } void main_loop(pqxx::connection &conn) diff --git a/bigscreen/rotatescreen.cpp b/bigscreen/rotatescreen.cpp new file mode 100644 index 0000000..0997e5c --- /dev/null +++ b/bigscreen/rotatescreen.cpp @@ -0,0 +1,78 @@ +#include +#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); +} + diff --git a/bigscreen/rotatescreen.h b/bigscreen/rotatescreen.h new file mode 100644 index 0000000..0883ca2 --- /dev/null +++ b/bigscreen/rotatescreen.h @@ -0,0 +1,39 @@ +#ifndef _ROTATESCREEN_H +#define _ROTATESCREEN_H 1 + +#include +#include +#include +#include "screen.h" + +/* + * Doesn't rotate the screens, but rotate _between_ them (ie. show + * one at a time). :-) + */ +struct Subscreen { + unsigned char *buf; + GenericScreen *screen; +}; + +class RotateScreen : public GenericScreen { +private: + bool valid; + std::vector subscreens; + unsigned current_screen; + + struct timeval last_update; + + bool needs_update(); + +public: + RotateScreen(); + virtual ~RotateScreen(); + + bool check_invalidated(); + void draw(unsigned char *buf); + + void add_screen(GenericScreen *screen); +// void remove_screen(GenericScreen *screen); +}; + +#endif /* !defined(_ROTATESCREEN_H) */ -- 2.39.2