From ef3e9f27177227a0f412e6f9995212b36bf27f19 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 20 Feb 2005 00:51:39 +0000 Subject: [PATCH] Added split screen functionality, for showing up to four groups at a time. --- bigscreen/Makefile | 2 +- bigscreen/ccbs_bigscreen.cpp | 24 ++++++++----- bigscreen/splitscreen.cpp | 70 ++++++++++++++++++++++++++++++++++++ bigscreen/splitscreen.h | 23 ++++++++++++ 4 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 bigscreen/splitscreen.cpp create mode 100644 bigscreen/splitscreen.h diff --git a/bigscreen/Makefile b/bigscreen/Makefile index 2303ff9..2afcd30 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 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 screen.o all: ccbs-bigscreen diff --git a/bigscreen/ccbs_bigscreen.cpp b/bigscreen/ccbs_bigscreen.cpp index fbbc0aa..2114093 100644 --- a/bigscreen/ccbs_bigscreen.cpp +++ b/bigscreen/ccbs_bigscreen.cpp @@ -11,10 +11,12 @@ #include "fetch_group.h" #include "fonts.h" #include "groupscreen.h" +#include "splitscreen.h" Tournament active_tournament; std::vector active_groups; std::vector screens; +SplitScreen *mainscreen = NULL; unsigned char framebuf[800 * 600 * 4], screenbuf[800 * 600 * 4]; void init(pqxx::connection &conn) @@ -24,6 +26,8 @@ void init(pqxx::connection &conn) } screens.erase(screens.begin(), screens.end()); + delete mainscreen; + conn.perform(FetchCurrentTournament(&active_tournament)); conn.perform(FetchListOfActiveGroups(&active_groups)); @@ -39,6 +43,14 @@ void init(pqxx::connection &conn) screens.push_back(new GroupScreen(conn, i->tournament, i->round, i->parallel)); } } + + // hack + screens.push_back(NULL); + screens.push_back(NULL); + screens.push_back(NULL); + screens.push_back(NULL); + + mainscreen = new SplitScreen(screens[0], screens[1], screens[2], screens[3]); } void main_loop(pqxx::connection &conn) @@ -49,17 +61,11 @@ void main_loop(pqxx::connection &conn) return; } - memset(framebuf, 0, 800*600*4); - - if (screens.size() > 0) { - if (screens[0]->check_invalidated()) { - screens[0]->draw(screenbuf); - } - - memcpy(framebuf, screenbuf, 800*600*4); + if (mainscreen->check_invalidated()) { + mainscreen->draw(framebuf); } - ptc_update(framebuf); + conn.await_notification(0, 50000); } diff --git a/bigscreen/splitscreen.cpp b/bigscreen/splitscreen.cpp new file mode 100644 index 0000000..a322fec --- /dev/null +++ b/bigscreen/splitscreen.cpp @@ -0,0 +1,70 @@ +#include +#include "splitscreen.h" + +SplitScreen::SplitScreen(GenericScreen *s1, GenericScreen *s2, GenericScreen *s3, GenericScreen *s4) + : valid(false) +{ + subscreens[0] = s1; + subscreens[1] = s2; + subscreens[2] = s3; + subscreens[3] = s4; + + memset(subbufs[0], 0, 800*600*4); + memset(subbufs[1], 0, 800*600*4); + memset(subbufs[2], 0, 800*600*4); + memset(subbufs[3], 0, 800*600*4); +} + +SplitScreen::~SplitScreen() +{ +} + +bool SplitScreen::check_invalidated() +{ + if (!valid) + return true; + + for (unsigned i = 0; i < 4; ++i) { + if (subscreens[i] && subscreens[i]->check_invalidated()) + return true; + } + + return false; +} + +void SplitScreen::draw(unsigned char *buf) +{ + for (unsigned i = 0; i < 4; ++i) { + if (subscreens[i] && subscreens[i]->check_invalidated()) { + subscreens[i]->draw(subbufs[i]); + } + } + + downscale_2x2(buf, subbufs[0]); + downscale_2x2(buf + 400 * 4, subbufs[1]); + downscale_2x2(buf + 800 * 300 * 4, subbufs[2]); + downscale_2x2(buf + 800 * 300 * 4 + 400 * 4, subbufs[3]); + + valid = true; +} + +// simple box filter (blah) +void SplitScreen::downscale_2x2(unsigned char *dst, unsigned char *src) +{ + for (unsigned y = 0; y < 300; ++y) { + unsigned char *sptr1 = src + (y*2) * 800 * 4; + unsigned char *sptr2 = src + (y*2+1) * 800 * 4; + unsigned char *dptr = dst + y * 800 * 4; + + for (unsigned x = 0; x < 400; ++x) { + *dptr++ = (sptr1[0] + sptr1[4] + sptr2[0] + sptr2[4]) >> 2; // red + *dptr++ = (sptr1[1] + sptr1[5] + sptr2[1] + sptr2[5]) >> 2; // green + *dptr++ = (sptr1[2] + sptr1[6] + sptr2[2] + sptr2[6]) >> 2; // blue + *dptr++ = (sptr1[3] + sptr1[7] + sptr2[3] + sptr2[7]) >> 2; // alpha + + sptr1 += 8; + sptr2 += 8; + } + } +} + diff --git a/bigscreen/splitscreen.h b/bigscreen/splitscreen.h new file mode 100644 index 0000000..3b0616c --- /dev/null +++ b/bigscreen/splitscreen.h @@ -0,0 +1,23 @@ +#ifndef _SPLITSCREEN_H +#define _SPLITSCREEN_H 1 + +#include "screen.h" + +/* A 4x4 split class */ +class SplitScreen : public GenericScreen { +private: + unsigned char subbufs[4][800 * 600 * 4]; + GenericScreen *subscreens[4]; + bool valid; + + void downscale_2x2(unsigned char *dst, unsigned char *src); + +public: + SplitScreen(GenericScreen *s1, GenericScreen *s2, GenericScreen *s3, GenericScreen *s4); + virtual ~SplitScreen(); + + bool check_invalidated(); + void draw(unsigned char *buf); +}; + +#endif /* !defined(_SPLITSCREEN_H) */ -- 2.39.2