Actually show a total for each player.
[ccbs] / bigscreen / groupscreen.cpp
1 #include <algorithm>
2
3 #include "groupscreen.h"
4 #include "fetch_group.h"
5 #include "fonts.h"
6
7 GroupScreen::GroupScreen(pqxx::connection &conn, unsigned tournament, unsigned round, unsigned parallel)
8         : tournament(tournament), round(round), parallel(parallel), scores_changed(conn, "scores"), conn(conn), valid(false)
9 {
10 }
11
12 GroupScreen::~GroupScreen()
13 {
14 }
15
16 bool GroupScreen::check_invalidated()
17 {
18         // we might want to do this slightly more sophisticated later, but for now this will do
19         return !valid || scores_changed.get_flag();
20 }
21
22 void GroupScreen::draw(unsigned char *buf)
23 {
24         scores_changed.reset_flag();
25
26         Group group;
27         conn.perform(FetchGroup(tournament, round, parallel, &group));
28
29         memset(buf, 0, 800 * 600 * 4);
30
31         // main heading
32         char heading[64];
33         if (parallel == 0) {
34                 sprintf(heading, "Round %u", round);
35         } else {
36                 sprintf(heading, "Round %u, Group %u", round, parallel);
37         }
38
39         {
40                 unsigned width = my_draw_text(heading, NULL, 48.0);
41                 my_draw_text(heading, buf, 48.0, 800/2 - width/2, 60);
42         }
43         
44         // Find out how wide each column has to be. First try unlimited width (ie.
45         // long titles for everything); if that gets too long, try again with short
46         // titles for chosen songs.
47         unsigned width[16], num_scores;
48         unsigned max_num_width = my_draw_text("8888", NULL, 22.0);
49         unsigned mode;
50         for (mode = 0; mode < 2; ++mode) {
51                 for (unsigned i = 0; i < 16; ++i)
52                         width[i] = 0;
53
54                 for (std::vector<Player>::const_iterator i = group.players.begin(); i != group.players.end(); ++i) {
55                         unsigned col = 1;
56                         width[0] = std::max(width[0], my_draw_text(i->nick, NULL, 18.0));
57
58                         for (std::vector<Score>::const_iterator j = i->scores.begin(); j != i->scores.end(); ++j, ++col) {
59                                 if (j->chosen) {
60                                         width[col] = std::max(width[col], my_draw_text((mode == 0) ? j->song.title : j->song.short_title, NULL, 12.0) + 
61                                                         max_num_width + 10);
62                                 } else {                
63                                         width[col] = std::max(width[col], my_draw_text(j->song.short_title, NULL, 12.0));
64                                         width[col] = std::max(width[col], max_num_width);
65                                 }
66                         }
67                 }
68
69                 num_scores = group.players[0].scores.size();
70
71                 width[num_scores + 1] = std::max(my_draw_text("Total", NULL, 12.0), max_num_width);
72                 width[num_scores + 2] = my_draw_text("Rank", NULL, 12.0);
73
74                 // if we're at long titles and that works, don't try the short ones
75                 if (mode == 0) {
76                         unsigned sumwidth = 0;
77                         for (unsigned i = 0; i <= num_scores + 2; ++i)
78                                 sumwidth += width[i] + 20;
79                         
80                         if (sumwidth < 800)
81                                 break;
82                 }
83         }
84
85         // make column headings from the first player's songs
86         unsigned col = 1;
87         unsigned x = 40 + width[0];
88         for (std::vector<Score>::const_iterator i = group.players[0].scores.begin(); i != group.players[0].scores.end(); ++i, ++col) {
89                 if (!i->chosen) {
90                         unsigned this_width = my_draw_text(i->song.short_title, NULL, 12.0);
91                         my_draw_text(i->song.short_title, buf, 12.0, x + width[col] / 2 - this_width / 2, 100);
92                 }
93                 x += width[col] + 20;
94         }
95
96         my_draw_text("Total", buf, 12.0, x + width[num_scores + 1] / 2 - my_draw_text("Total", NULL, 12.0) / 2, 100);
97         x += width[num_scores + 1] + 20;
98         my_draw_text("Rank", buf, 12.0, x + width[num_scores + 2] / 2 - my_draw_text("Rank", NULL, 12.0) / 2, 100);
99         
100         // show all the players and the scores
101         unsigned y = 140;
102         for (std::vector<Player>::const_iterator i = group.players.begin(); i != group.players.end(); ++i) {
103                 my_draw_text(i->nick, buf, 18.0, 20, y);
104
105                 unsigned x = 40 + width[0];
106
107                 unsigned col = 1;
108                 for (std::vector<Score>::const_iterator j = i->scores.begin(); j != i->scores.end(); ++j, ++col) {
109                         char text[16];
110                         sprintf(text, "%u", j->score);
111         
112                         unsigned this_width = my_draw_text(text, NULL, 22.0);
113                         if (j->chosen) {
114                                 if (j->score != -1) {
115                                         my_draw_text(text, buf, 22.0, x + max_num_width - this_width, y);
116                                 }
117                                 my_draw_text((mode == 0) ? j->song.title : j->song.short_title, buf, 12.0, x + max_num_width + 10, y);
118                         } else {
119                                 if (j->score != -1) {
120                                         my_draw_text(text, buf, 22.0, x + width[col] / 2 - this_width / 2, y);
121                                 }
122                         }
123                         x += width[col] + 20;
124                 }
125
126                 // draw total
127                 {
128                         char text[16];
129                         sprintf(text, "%u", i->total);
130                         
131                         unsigned this_width = my_draw_text(text, NULL, 22.0);
132                         my_draw_text(text, buf, 22.0, x + width[num_scores + 1] / 2 - this_width / 2, y);
133                         x += width[num_scores + 1] + 20;
134                 }
135
136                 y += 40;
137         }
138         
139         valid = true;
140 }
141