3 * Daniel Nelson - 12/8/1
5 * Copyright (C) 2000 Daniel Nelson
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Daniel Nelson - aluminumangel.org
35 #include "Displayer.h"
36 #include "MetaState.h"
40 GLuint
Displayer::score_to_beat_texture
;
41 GLuint
Displayer::record_textures
[DC_SCORE_REC_NUMBER_DRAW
];
42 GLubyte
**Displayer::record_texture_data
;
43 GLubyte
*Displayer::player_rank_texture_data
;
45 void Displayer::copyRecordSubTexture ( GLubyte
*texture
, GLubyte
*subtexture
,
46 int subtex_width
, int s_location
, int copy_width
)
48 for (int t
= DC_LETTER_TEX_LENGTH
; t
--; )
49 for (int s
= copy_width
; s
--; ) {
50 int ds
= s_location
+ s
;
52 texture
[(t
* DC_SCORE_REC_TEX_LENGTH_S
+ ds
) * 4 + 0]
53 = subtexture
[(t
* subtex_width
+ s
) * 4 + 0];
54 texture
[(t
* DC_SCORE_REC_TEX_LENGTH_S
+ ds
) * 4 + 1]
55 = subtexture
[(t
* subtex_width
+ s
) * 4 + 1];
56 texture
[(t
* DC_SCORE_REC_TEX_LENGTH_S
+ ds
) * 4 + 2]
57 = subtexture
[(t
* subtex_width
+ s
) * 4 + 2];
58 texture
[(t
* DC_SCORE_REC_TEX_LENGTH_S
+ ds
) * 4 + 3]
59 = subtexture
[(t
* subtex_width
+ s
) * 4 + 3];
63 void Displayer::rerankScoreRecord ( )
66 = new GLubyte
[DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_RANK_STRING_TEX_WIDTH
* 4];
68 for (int n
= Score::player_rank
; n
--; ) {
69 ostringstream rank_string
;
70 rank_string
<< (GC_SCORE_REC_LENGTH
- n
) << ends
;
72 for (int i
= DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_RANK_STRING_TEX_WIDTH
* 4;
76 String::fillStringTexture(rank_string
.str().data(), subtexture
,
77 DC_SCORE_REC_RANK_STRING_TEX_WIDTH
, true);
78 copyRecordSubTexture(record_texture_data
[n
], subtexture
,
79 DC_SCORE_REC_RANK_STRING_TEX_WIDTH
, DC_SCORE_REC_RANK_TEX_MARGIN
,
80 DC_SCORE_REC_RANK_STRING_TEX_WIDTH
);
83 if (subtexture
!= null
) {
89 void Displayer::generateScoreRankTexture ( int rank
, int score
,
90 const char *name
, GLubyte
*texture
)
92 ostringstream score_string
;
93 score_string
<< score
<< ends
;
95 ostringstream rank_string
;
96 rank_string
<< (GC_SCORE_REC_LENGTH
- rank
) << ends
;
99 = String::stringWidth(score_string
.str().data(), DC_SCORE_REC_TEX_LENGTH_S
-
100 2 * DC_SCORE_REC_RANK_TEX_MARGIN
);
102 int max_name_width
= (DC_SCORE_REC_TEX_LENGTH_S
103 - 2 * DC_SCORE_REC_RANK_TEX_MARGIN
- DC_SCORE_REC_RANK_MIN_SPACE
104 - DC_SCORE_REC_RANK_STRING_TEX_WIDTH
) - score_width
;
105 int name_width
= String::stringWidth(name
, max_name_width
);
107 int subtex_width
= name_width
> score_width
? name_width
: score_width
;
108 if (DC_SCORE_REC_RANK_STRING_TEX_WIDTH
> subtex_width
)
109 subtex_width
= DC_SCORE_REC_RANK_STRING_TEX_WIDTH
;
111 = new GLubyte
[DC_LETTER_TEX_LENGTH
* subtex_width
* 4];
113 for (int i
= DC_LETTER_TEX_LENGTH
* subtex_width
* 4; i
--; )
115 String::fillStringTexture(rank_string
.str().data(), subtexture
,
116 DC_SCORE_REC_RANK_STRING_TEX_WIDTH
, true, subtex_width
);
117 copyRecordSubTexture(texture
, subtexture
, subtex_width
,
118 DC_SCORE_REC_RANK_TEX_MARGIN
, DC_SCORE_REC_RANK_STRING_TEX_WIDTH
);
120 for (int i
= DC_LETTER_TEX_LENGTH
* subtex_width
* 4; i
--; )
122 String::fillStringTexture(name
, subtexture
, name_width
, true, subtex_width
);
123 copyRecordSubTexture(texture
, subtexture
, subtex_width
,
124 DC_SCORE_REC_RANK_STRING_TEX_WIDTH
+ DC_SCORE_REC_RANK_TEX_MARGIN
,
127 for (int i
= DC_LETTER_TEX_LENGTH
* subtex_width
* 4; i
--; )
129 String::fillStringTexture(score_string
.str().data(), subtexture
, score_width
, true,
131 copyRecordSubTexture(texture
, subtexture
, subtex_width
,
132 (DC_SCORE_REC_TEX_LENGTH_S
- DC_SCORE_REC_RANK_TEX_MARGIN
)
133 - score_width
, score_width
);
135 if (subtexture
!= null
) {
136 delete [] subtexture
;
141 void Displayer::generateScoreRecord ( )
143 if (!(MetaState::mode
& CM_SOLO
)) return;
145 // generate score to beat message
147 glGenTextures(1, &score_to_beat_texture
);
149 glBindTexture(GL_TEXTURE_2D
, score_to_beat_texture
);
151 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
152 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
153 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
154 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
156 GLubyte texture
[DC_SCORE_TO_BEAT_TEX_LENGTH_T
]
157 [DC_SCORE_TO_BEAT_TEX_LENGTH_S
][3];
158 for (int t
= DC_SCORE_TO_BEAT_TEX_LENGTH_T
; t
--; )
159 for (int s
= DC_SCORE_TO_BEAT_TEX_LENGTH_S
; s
--; )
160 texture
[t
][s
][0] = texture
[t
][s
][1] = texture
[t
][s
][2] = 0;
162 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, DC_SCORE_TO_BEAT_TEX_LENGTH_S
,
163 DC_SCORE_TO_BEAT_TEX_LENGTH_T
, GL_FALSE
, GL_RGB
, GL_UNSIGNED_BYTE
,
166 int width
= String::stringWidth(DC_SCORE_TO_BEAT_MESSAGE
,
167 DC_SCORE_TO_BEAT_TEX_LENGTH_S
);
168 GLubyte
*subtexture
= new GLubyte
[DC_LETTER_TEX_LENGTH
* width
* 4];
169 String::fillStringTexture(DC_SCORE_TO_BEAT_MESSAGE
, subtexture
, width
);
170 glTexSubImage2D(GL_TEXTURE_2D
, 0, (DC_SCORE_TO_BEAT_TEX_LENGTH_S
- width
)
171 / 2, (30 * DC_SCORE_TO_BEAT_TEX_LENGTH_T
/ 100 - DC_LETTER_TEX_LENGTH
) / 2,
172 width
, DC_LETTER_TEX_LENGTH
, GL_RGBA
, GL_UNSIGNED_BYTE
, subtexture
);
173 if (subtexture
!= null
) {
174 delete [] subtexture
;
178 width
= String::stringWidth(Score::record
[GC_SCORE_REC_LENGTH
- 1].name
,
179 DC_SCORE_TO_BEAT_TEX_LENGTH_S
);
180 subtexture
= new GLubyte
[DC_LETTER_TEX_LENGTH
* width
* 4];
181 String::fillStringTexture(Score::record
[GC_SCORE_REC_LENGTH
- 1].name
,
183 glTexSubImage2D(GL_TEXTURE_2D
, 0, (DC_SCORE_TO_BEAT_TEX_LENGTH_S
- width
)
184 / 2, (117 * DC_SCORE_TO_BEAT_TEX_LENGTH_T
/ 100 - DC_LETTER_TEX_LENGTH
) / 2,
185 width
, DC_LETTER_TEX_LENGTH
, GL_RGBA
, GL_UNSIGNED_BYTE
, subtexture
);
186 if (subtexture
!= null
) {
187 delete [] subtexture
;
192 score
<< Score::record
[GC_SCORE_REC_LENGTH
- 1].score
<< ends
;
194 width
= String::stringWidth(score
.str().data(), DC_SCORE_TO_BEAT_TEX_LENGTH_S
);
195 subtexture
= new GLubyte
[DC_LETTER_TEX_LENGTH
* width
* 4];
196 String::fillStringTexture(score
.str().data(), subtexture
, width
);
197 glTexSubImage2D(GL_TEXTURE_2D
, 0, (DC_SCORE_TO_BEAT_TEX_LENGTH_S
- width
)
198 / 2, (170 * DC_SCORE_TO_BEAT_TEX_LENGTH_T
/ 100 - DC_LETTER_TEX_LENGTH
) / 2,
199 width
, DC_LETTER_TEX_LENGTH
, GL_RGBA
, GL_UNSIGNED_BYTE
, subtexture
);
200 if (subtexture
!= null
) {
201 delete [] subtexture
;
205 // generate rank textures
207 record_texture_data
= new GLubyte
*[GC_SCORE_REC_LENGTH
- 1];
209 for (int n
= GC_SCORE_REC_LENGTH
- 1; n
--; ) {
210 record_texture_data
[n
]
211 = new GLubyte
[DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_TEX_LENGTH_S
* 4];
212 for (int i
= DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_TEX_LENGTH_S
* 4;
214 record_texture_data
[n
][i
] = 0;
216 generateScoreRankTexture(n
+ 1, Score::record
[n
+ 1].score
,
217 Score::record
[n
+ 1].name
, record_texture_data
[n
]);
220 // ready space for the player's rank texture
222 player_rank_texture_data
223 = new GLubyte
[DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_TEX_LENGTH_S
* 4];
224 for (int i
= DC_LETTER_TEX_LENGTH
* DC_SCORE_REC_TEX_LENGTH_S
* 4; i
--; )
225 player_rank_texture_data
[i
] = 0;