#include #include #include #include #include"mino.h" #include"graph.h" #include"input.h" #include"core.h" #define DELAY_FALL 0.2 #define DELAY_BAKE 1.0 #define GRID_W 10 #define GRID_H 20 #define GRID_X 32 #define GRID_Y 32 #define CELL_W 32 #define CELL_H 32 _ mat4 proj; _ S8 grid[GRID_H][GRID_W]={0};/*indexes into tetros,-1 for nothing*/ _ Tetro tetros[]={ {0,{0,0},{1.5,1.5}, {{0,1},{1,1},{2,1},{3,1}}}, {1,{0,0},{1,1}, {{0,0},{0,1},{1,1},{2,1}}}, {2,{0,0},{1,1}, {{2,0},{0,1},{1,1},{2,1}}}, {3,{0,0},{1,1}, {{1,0},{0,1},{1,1},{2,1}}}, {4,{0,0},{1,1}, {{1,0},{2,0},{0,1},{1,1}}}, {5,{0,0},{1,1}, {{0,0},{1,0},{1,1},{2,1}}}, {6,{0,0},{0.5,0.5}, {{0,0},{1,0},{0,1},{1,1}}}}; _ C tetros_c[]="IJLTSZO"; _ vec4 tetros_col[]={{0,1,1,1},{0,0,1,1},{1,0.5,0,1},{1,0,1,1},{1,0,0,1},{0,1,0,1},{1,1,0,1}}; _ U32 tex_cell_grid,tex_cell_mino,tex_cell_soon; _ U32 shader_tetro; _ IM C shader_tetro_vert[]=GRAPH_GLSL( layout (location=0) in vec3 pos; layout (location=1) in vec2 tex; out vec2 Tex; uniform mat4 proj; uniform mat4 model; void main(){gl_Position=proj*model*vec4(pos,1);Tex=tex;}); _ IM C shader_tetro_frag[]=GRAPH_GLSL( out vec4 Frag; in vec2 Tex; uniform vec4 col; uniform sampler2D buf; void main(){Frag=texture(buf,Tex)*col;}); _ V shader_tetro_init(V){ shader_tetro=graph_shader_create(shader_tetro_vert,shader_tetro_frag), graph_shader_use(shader_tetro), graph_shader_setM4("proj",proj), graph_shader_setV4("col",(vec4){1,1,1,1}), graph_shader_setI("buf",0);} _ V tetro_trans(Tetro*t,vec2 m){ glm_vec2_add(t->pos,m,t->pos);} _ V tetro_rot(Tetro*t,S8 c){U8 i;vec2 a; for(i=0;i<4;++i){ glm_vec2_sub(t->org,t->v[i],a), glm_vec2_rotate(a,GLM_PI_2*(2-c),a), glm_vec2_add(a,t->org,a), glm_vec2_copy(a,t->v[i]);}} _ V tetro_bake(Tetro t){U8 i;vec2 a; glm_vec2_sub(t.pos,(vec2){GRID_X,GRID_Y},a), glm_vec2_div(a,(vec2){CELL_W,CELL_H},a); for(i=0;i<4;++i)grid[(U32)(a[1]+t.v[i][1])][(U32)(a[0]+t.v[i][0])]=t.i;} _ V tetro_draw_col(Tetro t,vec4 c){U8 i;vec2 a;vec2 z={CELL_W,CELL_H}; graph_shader_use(shader_tetro), graph_tex_use(tex_cell_mino,0), graph_shader_setM4("proj",proj), graph_shader_setV4("col",c); for(i=0;i<4;++i){ glm_vec2_mul(t.v[i],z,a), glm_vec2_add(t.pos,a,a), graph_quad(a,z);}} _ V tetro_draw(Tetro t){tetro_draw_col(t,tetros_col[t.i]);} _ U8 tetro_in_floor(Tetro t){U8 i;U32 w,x;vec2 a; glm_vec2_sub(t.pos,(vec2){GRID_X,GRID_Y},a), glm_vec2_div(a,(vec2){CELL_W,CELL_H},a); for(i=0;i<4;++i){w=a[1]+t.v[i][1],x=a[0]+t.v[i][0];Q(w>=GRID_H||w<0,R 1)Q(-1!=grid[w][x],R 1)} R 0;} _ U8 tetro_in_wall(Tetro t){U8 i;U32 w,x;vec2 a; glm_vec2_sub(t.pos,(vec2){GRID_X,GRID_Y},a), glm_vec2_div(a,(vec2){CELL_W,CELL_H},a); for(i=0;i<4;++i){w=a[1]+t.v[i][1],x=a[0]+t.v[i][0];Q(x>=GRID_W||x<0,R 1)Q(-1!=grid[w][x],R 1)} R 0;} _ Tetro bag[14]; _ U8 bag_i=14; _ V tetro_next(Tetro*t){U8 i,j;Tetro u; Q(bag_i>=13,bag_i=0,memcpy(bag,tetros,SZ tetros),memcpy(bag+7,tetros,SZ tetros); for(i=0;i<13;++i)j=i+rand()/(RAND_MAX/(14-i)+1),u=bag[j],bag[j]=bag[i],bag[i]=u;) OR ++bag_i;*t=bag[bag_i],t->pos[0]=GRID_X+CELL_W*4,t->pos[1]=GRID_Y+CELL_H*(GRID_H-1);} _ V tetro_fall(Tetro*t,F64 dt){_ F64 et=0;U8 q; t->pos[1]-=CELL_H,q=tetro_in_floor(*t),t->pos[1]+=CELL_H; Q(q,Q(et>=DELAY_BAKE,tetro_bake(*t),tetro_next(t),et=0)OR et+=dt) OR tetro_trans(t,(vec2){0,-32});} _ V tetro_move(Tetro*t,F64 x){ tetro_trans(t,(vec2){x,0}); Q(tetro_in_wall(*t),tetro_trans(t,(vec2){-x,0}))} _ V grid_draw(V){U8 i,j;S8 c;vec2 z={CELL_W,CELL_H},pos={GRID_X,GRID_Y}; graph_shader_use(shader_tetro), graph_shader_setM4("proj",proj); for(i=0;i=DELAY_FALL,tetro_fall(&held,et),et=0) Q(IB_Z&b.p,tetro_rot(&held, 1)) Q(IB_X&b.p,tetro_rot(&held,-1)) Q(IB_C&b.p,tetro_next(&held)) Q(IB_L&b.p,tetro_move(&held,-32)) Q(IB_R&b.p,tetro_move(&held, 32)) Q(IB_1&b.p,tetro_bake(held))}