diff --git a/src/render.cpp b/src/render.cpp index 84a1db6..2bcd9f7 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -265,6 +265,43 @@ static inline int max(int a, int b) return b; } +void render_text(struct mesh plane_mesh, + uint uniform_trans, + uint uniform_texture_trans, + const char ** text, + int text_length, + float aspect, + mat4x4 a, + mat4x4 s, + mat4x4 r) +{ + int h_advance = 0; + int v_advance = 0; + + for (int i = 0; i < text_length; i++) { + const char * txt = text[i]; + while (*txt) { + char c = *txt++; + + if (c != ' ') { + mat4x4 char_t = translate(vec3(-2 * 16 + h_advance / 8.0f, + -3.0f * aspect + -v_advance / 16.0f, 0)); + mat4x4 trans = a * scale(12.0f / vp_height) * s * char_t * r; + + mat4x4 texture_trans = char_tex_trans(c); + + glUniform4fv(uniform_trans, 4, &trans[0][0]); + glUniform4fv(uniform_texture_trans, 4, &texture_trans[0][0]); + glDrawElements(GL_TRIANGLES, plane_mesh.length, GL_UNSIGNED_INT, 0); + } + + h_advance += grid_width; + } + v_advance += grid_height; + h_advance = 0; + } +} + void render_font(struct mesh plane_mesh, uint attrib_position, uint attrib_texture, @@ -302,6 +339,70 @@ void render_font(struct mesh plane_mesh, mat4x4 r = rotate_y(PI / 1.0f) * rotate_z(PI / 1.0f) * rotate_x(PI / 2.0f); glUniform1i(uniform_texture0, 0); + glUniform1f(uniform_time, state->time); + + ////////////////////////////////////////////////////////////////////// + // instructions + ////////////////////////////////////////////////////////////////////// + + const char * intro[] = { + "This game requires a gamepad.", + "Keyboard is not supported.", + "PlayStation DualShock 4 recommended.", + "Press cross to launch ball(s).", + "Analog triggers to move paddle.", + "Finish level 1 before the timer elapses.", + }; + const int intro_length = (sizeof (intro)) / (sizeof (intro[0])); + + const char * loss[] = { + "You were not successful.", + "Press option to retry.", + }; + const int loss_length = (sizeof (loss)) / (sizeof (loss[0])); + + const char * win[] = { + "Your performance is satisfactory.", + }; + const int win_length = (sizeof (win)) / (sizeof (win[0])); + + if (state->balls_launched == 0) { + vec3 base_color = vec3(1, 1, 1); + glUniform3fv(uniform_base_color, 1, &base_color[0]); + render_text(plane_mesh, + uniform_trans, + uniform_texture_trans, + intro, + intro_length, + aspect, + a, s, r); + } else if (state->remaining <= 0) { + if (1) { + vec3 base_color = vec3(1, 0.1, 0.1); + glUniform3fv(uniform_base_color, 1, &base_color[0]); + render_text(plane_mesh, + uniform_trans, + uniform_texture_trans, + loss, + loss_length, + aspect, + a, s, r); + } else { + vec3 base_color = vec3(0.1, 1.0, 0.1); + glUniform3fv(uniform_base_color, 1, &base_color[0]); + render_text(plane_mesh, + uniform_trans, + uniform_texture_trans, + win, + win_length, + aspect, + a, s, r); + } + } + + ////////////////////////////////////////////////////////////////////// + // remaining + ////////////////////////////////////////////////////////////////////// char dst[64]; @@ -316,22 +417,24 @@ void render_font(struct mesh plane_mesh, //base_color = vec3(1, 0.1, 0.1); } - glUniform1f(uniform_time, state->time); glUniform3fv(uniform_base_color, 1, &base_color[0]); - int advance = 0; + int h_advance = grid_width * 10; + int v_advance = grid_height * 5; + for (int i = 0; i < len; i++) { if (dst[i] != ' ') { mat4x4 texture_trans = char_tex_trans(dst[i]); - mat4x4 char_t = translate(vec3(advance / 8.0f, -8.0f * aspect, 0)); - mat4x4 trans = a * scale(32.0f / vp_height) * s * char_t * r; + mat4x4 char_t = translate(vec3(-2 * 16 + h_advance / 8.0f, + -1.0f * aspect + -v_advance / 16.0f, 0)); + mat4x4 trans = a * scale(26.0f / vp_height) * s * char_t * r; glUniform4fv(uniform_trans, 4, &trans[0][0]); glUniform4fv(uniform_texture_trans, 4, &texture_trans[0][0]); glDrawElements(GL_TRIANGLES, plane_mesh.length, GL_UNSIGNED_INT, 0); } - advance += grid_width; + h_advance += grid_width; } } @@ -357,7 +460,12 @@ void render_background(struct mesh plane_mesh, mat4x4 r = rotate_y(PI / 1.0f) * rotate_z(PI / 1.0f) * rotate_x(PI / 2.0f); mat4x4 trans = r; glUniform4fv(uniform_trans, 4, &trans[0][0]); - glUniform1f(uniform_time, state->time); + + if (state->balls_launched == 0 || state->remaining <= 0.0) { + glUniform1f(uniform_time, 0); + } else { + glUniform1f(uniform_time, state->time); + } vec2 resolution = vec2(vp_width, vp_height); glUniform2fv(uniform_resolution, 1, &resolution[0]); diff --git a/src/shader/font.fp.glsl b/src/shader/font.fp.glsl index 623b874..ea73c62 100644 --- a/src/shader/font.fp.glsl +++ b/src/shader/font.fp.glsl @@ -26,7 +26,7 @@ void main() float red_alpha = (1.0 - length(uv) + sin(time * 3) * abs(sin(time + uv.x * 2 + uv.y * 2))); - float alpha = (base_color.y == 1.0) ? 1.0 : red_alpha; + float alpha = (base_color.x == 1.0 && base_color.y == 1.0 && base_color.z == 1.0) ? 1.0 : red_alpha; gl_FragColor = vec4(base_color * (i + alpha), 1.0); //gl_FragColor = vec4(d, d, d, 1); //gl_FragColor = vec4(fp_position.xy, 0, 1.0); diff --git a/src/update.cpp b/src/update.cpp index db3bbf8..64bd41e 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -153,11 +153,13 @@ void update_ball(struct game_state * state, struct ball_state& ball, double time void update(struct game_state * state, double time) { - for (int i = 0; i < state->balls_launched; i++) { - if (state->balls[i].ball_y > 30.0f) - continue; + if (state->remaining >= 0.0) { + for (int i = 0; i < state->balls_launched; i++) { + if (state->balls[i].ball_y > 30.0f) + continue; - update_ball(state, state->balls[i], time); + update_ball(state, state->balls[i], time); + } } if (state->balls_launched == 0) {