]> git.sesse.net Git - ccbs/blob - bigscreen/splitscreen.cpp
Implement a simple priority system.
[ccbs] / bigscreen / splitscreen.cpp
1 #include <cstring>
2 #include "splitscreen.h"
3
4 SplitScreen::SplitScreen(GenericScreen *s1, GenericScreen *s2, GenericScreen *s3, GenericScreen *s4)
5         : valid(false)
6 {
7         subscreens[0] = s1;
8         subscreens[1] = s2;
9         subscreens[2] = s3;
10         subscreens[3] = s4;
11
12         memset(subbufs[0], 0, 800*600*4);
13         memset(subbufs[1], 0, 800*600*4);
14         memset(subbufs[2], 0, 800*600*4);
15         memset(subbufs[3], 0, 800*600*4);
16 }
17
18 SplitScreen::~SplitScreen()
19 {
20 }
21
22 bool SplitScreen::check_invalidated()
23 {
24         if (!valid)
25                 return true;
26         
27         for (unsigned i = 0; i < 4; ++i) {
28                 if (subscreens[i] && subscreens[i]->check_invalidated())
29                         return true;
30         }
31
32         return false;
33 }
34
35 void SplitScreen::draw(unsigned char *buf)
36 {
37         for (unsigned i = 0; i < 4; ++i) {
38                 if (subscreens[i] && subscreens[i]->check_invalidated()) {
39                         subscreens[i]->draw(subbufs[i]);
40                 }
41         }
42         
43         downscale_2x2(buf, subbufs[0]);
44         downscale_2x2(buf + 400 * 4, subbufs[1]);
45         downscale_2x2(buf + 800 * 300 * 4, subbufs[2]);
46         downscale_2x2(buf + 800 * 300 * 4 + 400 * 4, subbufs[3]); 
47
48         // make divider lines
49         unsigned char *ptr = buf + 300 * 800 * 4;
50         for (unsigned x = 0; x < 800; ++x) {
51                 *ptr++ = 255;
52                 *ptr++ = 255;
53                 *ptr++ = 255;
54                 *ptr++ = 0;
55         }
56         
57         ptr = buf + 400 * 4;
58         for (unsigned y = 0; y < 600; ++y) {
59                 ptr[0] = 255;
60                 ptr[1] = 255;
61                 ptr[2] = 255;
62                 ptr[3] = 0;
63
64                 ptr += 800 * 4;
65         }
66         
67         valid = true;
68 }
69         
70 // simple box filter (blah)
71 void SplitScreen::downscale_2x2(unsigned char *dst, unsigned char *src)
72 {
73         for (unsigned y = 0; y < 300; ++y) {
74                 unsigned char *sptr1 = src + (y*2) * 800 * 4;
75                 unsigned char *sptr2 = src + (y*2+1) * 800 * 4;
76                 unsigned char *dptr = dst + y * 800 * 4;
77                 
78                 for (unsigned x = 0; x < 400; ++x) {
79                         *dptr++ = (sptr1[0] + sptr1[4] + sptr2[0] + sptr2[4]) >> 2;  // red
80                         *dptr++ = (sptr1[1] + sptr1[5] + sptr2[1] + sptr2[5]) >> 2;  // green
81                         *dptr++ = (sptr1[2] + sptr1[6] + sptr2[2] + sptr2[6]) >> 2;  // blue
82                         *dptr++ = (sptr1[3] + sptr1[7] + sptr2[3] + sptr2[7]) >> 2;  // alpha
83
84                         sptr1 += 8;
85                         sptr2 += 8;
86                 }
87         }
88 }
89