#include <stdio.h>
#include "../include/linmath.h"
#include "bigh.h"
#include GLAD_PATH
#include SDL_PATH
void reset_game_state(GameWorld* GW, GameVars* GV, GameData* GD) {
GW->level = GD->levels[GV->current_level];
GV->game_state = IN_PROGRESS;
GV->continues = 3;
GV->bricks_left = GW->level.bricks_count;
GV->score = 0;
}
void set_texture(GameData* GD, int index, unsigned int texture) {
GD->res.textures[index] = texture;
}
void set_shape(GameData* GD, int index, Shape shape) {
GD->res.shapes[index] = shape;
}
void game_init(GameWorld* GW, GameVars* GV, GameData* GD) {
float w = (float)GD->width;
float h = (float)GD->height;
unsigned int shader_sprite = shader_create("src/shaders/vs_cube.glsl", "src/shaders/fs_sprite.glsl");
unsigned int shader_text = shader_create("src/shaders/vs_text.glsl", "src/shaders/fs_text.glsl");
unsigned int shader_tile = shader_create("src/shaders/vs_cube.glsl", "src/shaders/fs_tile.glsl");
mat4x4 mat_proj;
mat4x4_identity(mat_proj);
mat4x4_ortho(mat_proj, -(float)GD->interface_size, w, 0.0f, h, -10.0f, 10.0f);
// mat4x4_perspective(mat_proj, deg_to_rad(45), w/h, 0.1f, 100000.0f);
glUseProgram(shader_sprite);
shader_set_int(shader_sprite, "image", 0);
shader_set_mat4x4(shader_sprite, "projection", mat_proj);
Shape basic_obj = sprite_init(shader_sprite);
glUseProgram(shader_text);
shader_set_int(shader_text, "image", 0);
shader_set_mat4x4(shader_text, "projection", mat_proj);
Shape text_obj = sprite_init(shader_text);
glUseProgram(shader_tile);
shader_set_int(shader_tile, "image", 0);
vec2 tile_size = {1.f, 900.f/64.f};
shader_set_vec2(shader_tile, "tex_ratio", tile_size);
shader_set_mat4x4(shader_tile, "projection", mat_proj);
Shape tiled_obj = sprite_init(shader_tile);
set_texture(GD, GO_BLOCK, texture_load("img/block.png"));
set_texture(GD, GO_BLOCK_SOLID, texture_load("img/tex2.png"));
set_texture(GD, GO_BACKGROUND, texture_load("img/tile_grass1.png"));
set_texture(GD, GO_PADDLE, texture_load("img/paddle2.png"));
set_texture(GD, GO_BALL, texture_load("img/goatball.png"));
set_texture(GD, GO_TEXT, texture_load("img/font.png"));
set_texture(GD, GO_INTERFACE, texture_load("img/tile_border.png"));
set_texture(GD, GO_POPUP, texture_load("img/popup.png"));
set_shape(GD, GO_EMPTY, basic_obj);
set_shape(GD, GO_BLOCK, basic_obj);
set_shape(GD, GO_BLOCK_SOLID, basic_obj);
set_shape(GD, GO_BACKGROUND, basic_obj);
set_shape(GD, GO_PADDLE, basic_obj);
set_shape(GD, GO_BALL, basic_obj);
set_shape(GD, GO_TEXT, text_obj);
set_shape(GD, GO_INTERFACE, tiled_obj);
set_shape(GD, GO_POPUP, basic_obj);
init_text(GW, GV, GD);
init_interface(GW, GV, GD);
reset_paddle(GW, GV, GD);
reset_ball(GW, GV, GD);
GV->wireframe = 0;
GV->timing = 1.0f;
GV->paddle_max_speed = 1.7f;
GV->paddle_acceleration = 0.8f;
GV->current_level = 0;
GV->score = 0;
GV->score_bonus = 0;
reset_game_state(GW, GV, GD);
// GW->popup.state = ENABLED;
// GW->text_popup.m.state = ENABLED;
}
void game_update(GameWorld* GW, GameVars* GV, GameData* GD, float dt) {
switch (GV->game_state) {
case IN_PROGRESS :
GV->timing = 1.0f;
GW->ball.timing = 1.0f;
ball_move(GW, GV, GD, dt);
paddle_move(GW, GV, GD, dt);
if (GV->bricks_left == 0) {
GV->game_state = WON;
}
for (int i=0; i < GW->level.obj_count; ++i) {
WO_update(GW, GV, GD, &(GW->level.bricks[i]), dt);
}
break;
case WON :
GW->popup.state = ENABLED;
GW->text_popup.m.state = ENABLED;
if (GV->score > GD->levels[GV->current_level].highscore) {
GD->levels[GV->current_level].highscore = GV->score;
}
ball_move(GW, GV, GD, dt);
break;
case NEXT :
GW->popup.state = DISABLED;
GW->text_popup.m.state = DISABLED;
if (GV->current_level < GD->level_count - 1) {
++ GV->current_level;
// GW->level = GD->levels[GV->current_level];
reset_game_state(GW, GV, GD);
reset_paddle(GW, GV, GD);
reset_ball(GW, GV, GD);
} else {
GW->background.rotation += 0.5f;
}
break;
case OUT :
GV->continues -= 1;
if (GV->continues <= 0) {
GV->game_state = LOST;
} else {
reset_ball(GW, GV, GD);
reset_paddle(GW, GV, GD);
GV->game_state = IN_PROGRESS;
}
break;
case PAUSE1 :
// GV->timing = 0.0f;
GW->ball.timing = 0.0f;
ball_move(GW, GV, GD, dt);
paddle_move(GW, GV, GD, dt);
for (int i=0; i < GW->level.obj_count; ++i) {
WO_update(GW, GV, GD, &(GW->level.bricks[i]), dt);
}
break;
case LOST :
GV->game_state = QUIT;
break;
default :
break;
}
}
void game_render(GameWorld* GW, GameVars* GV, GameData* GD) {
if (GV->wireframe == 1) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
} else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
shape_draw(GD, &GW->interface);
shape_draw(GD, &GW->background);
shape_draw(GD, &GW->paddle);
for (int i=0; i < GW->level.obj_count; ++i) {
shape_draw(GD, &(GW->level.bricks[i]));
// shape_draw(GD, &(GD->levels[GV->current_level].bricks[i]));
}
shape_draw(GD, &GW->ball.m);
shape_draw(GD, &GW->popup);
sprintf(GW->text_level.text, "LEVEL %d/%d", GV->current_level+1, GD->level_count);
WO_text_draw(GD, &GW->text_level);
sprintf(GW->text_score.text, "Score");
WO_text_draw_xy(GD, &GW->text_score, -180.f, 310.f);
sprintf(GW->text_score.text, "%d", GV->score);
WO_text_draw_xy(GD, &GW->text_score, -180.f, 240.f);
sprintf(GW->text_score.text, "Top ");
WO_text_draw_xy(GD, &GW->text_score, -180.f, 170.f);
sprintf(GW->text_score.text, "%d", GD->levels[GV->current_level].highscore);
WO_text_draw_xy(GD, &GW->text_score, -180.f, 100.f);
if (GV->score > GW->level.highscore) {
sprintf(GW->text_popup.text, "Nouveau record !\n%d points !", GV->score);
} else {
sprintf(GW->text_popup.text, "Ouais ! Ca vous fait %d points bien merites.", GV->score);
}
WO_text_boxdraw(GD, &GW->text_popup, 450.f);
}