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
#include "fetch_group.h"
#include "fonts.h"
#include "groupscreen.h"
+#include "splitscreen.h"
Tournament active_tournament;
std::vector<SkeletonGroup> active_groups;
std::vector<GenericScreen *> screens;
+SplitScreen *mainscreen = NULL;
unsigned char framebuf[800 * 600 * 4], screenbuf[800 * 600 * 4];
void init(pqxx::connection &conn)
}
screens.erase(screens.begin(), screens.end());
+ delete mainscreen;
+
conn.perform(FetchCurrentTournament(&active_tournament));
conn.perform(FetchListOfActiveGroups(&active_groups));
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)
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);
}
--- /dev/null
+#include <cstring>
+#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;
+ }
+ }
+}
+
--- /dev/null
+#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) */