Skip to content

Instantly share code, notes, and snippets.

@2bt
Created January 20, 2014 09:50
Show Gist options
  • Select an option

  • Save 2bt/8517569 to your computer and use it in GitHub Desktop.

Select an option

Save 2bt/8517569 to your computer and use it in GitHub Desktop.

Revisions

  1. 2bt created this gist Jan 20, 2014.
    160 changes: 160 additions & 0 deletions tetris.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,160 @@
    #include <SDL/SDL.h>
    #include <stdio.h>
    #include <time.h>

    enum {
    CELL_SIZE = 20,
    GRID_WIDTH = 10,
    GRID_HEIGHT = 20,
    };

    const char STONE_DATA[][16] = {
    {0x0,0xa,0x0,0x0,0x5,0xf,0x5,0x5,0x0,0xa,0x0,0x0,0x0,0xa}, // I
    {0x0,0x0,0x0,0x0,0x0,0xf,0xf,0x0,0x0,0xf,0xf}, // O
    {0x4,0x5,0x8,0x0,0xa,0xf,0xa,0x0,0x2,0x5,0x1}, // L


    };



    SDL_Surface* screen;

    void draw_cell(int x, int y, uint32_t c) {
    SDL_Rect rect = {
    x * CELL_SIZE, y * CELL_SIZE,
    CELL_SIZE, CELL_SIZE
    };
    SDL_FillRect(screen, &rect, c);
    }


    int pos_x;
    int pos_y;
    int rotation;
    int stone;
    int cells[GRID_HEIGHT][GRID_WIDTH];


    int collision(void) {
    int i;
    for (i = 0; i < 16; i++) {
    if (STONE_DATA[stone][i] >> rotation & 1) {
    int x = pos_x + i % 4;
    int y = pos_y + i / 4;
    if (x < 0 || x >= GRID_WIDTH || y >= GRID_HEIGHT) return 1;
    if (y >= 0 && cells[y][x]) return 1;
    }
    }
    return 0;
    }

    void new_stone(void) {
    pos_x = GRID_WIDTH / 2 - 2;
    pos_y = -1;
    stone = rand() % (sizeof(STONE_DATA) / sizeof(STONE_DATA[0]));
    rotation = rand() % 4;
    }

    void update(int dx, int dy, int rot) {

    int old_rot = rotation;
    rotation = (rotation + rot + 4) % 4;
    if (collision()) rotation = old_rot;

    pos_x += dx;
    if (collision()) pos_x -= dx;


    pos_y += dy;
    if (collision()) {
    pos_y -= dy;

    int i;
    for (i = 0; i < 16; i++) {
    if (STONE_DATA[stone][i] >> rotation & 1) {
    cells[pos_y + i / 4][pos_x + i % 4] = 1;
    }
    }


    new_stone();
    }


    }

    void draw(void) {
    SDL_FillRect(screen, NULL, 0x222222);
    int x, y, i;
    for (i = 0; i < 16; i++) {
    if (STONE_DATA[stone][i] >> rotation & 1) {
    draw_cell(pos_x + i % 4, pos_y + i / 4, 0xffffff);
    }
    }
    for (y = 0; y < GRID_HEIGHT; y++) {
    for (x = 0; x < GRID_WIDTH; x++) {
    if (cells[y][x]) draw_cell(x, y, 0x0000ff);
    }
    }
    }



    int main(int argc, char** argv) {

    srand(time(NULL));

    SDL_Init(SDL_INIT_VIDEO);
    screen = SDL_SetVideoMode(
    GRID_WIDTH * CELL_SIZE,
    GRID_HEIGHT * CELL_SIZE,
    32, SDL_HWSURFACE | SDL_DOUBLEBUF);


    if (!screen) {
    SDL_Quit();
    return 1;
    }

    SDL_EnableKeyRepeat(100, 50);

    new_stone();

    int running = 1;
    while (running) {

    int dx = 0;
    int dy = 0;
    int rot = 0;

    SDL_Event event;
    while (SDL_PollEvent(&event)) {
    switch (event.type) {
    case SDL_KEYDOWN:
    if (event.key.keysym.sym == SDLK_ESCAPE) running = 0;
    if (event.key.keysym.sym == SDLK_LEFT) dx--;
    if (event.key.keysym.sym == SDLK_RIGHT) dx++;
    if (event.key.keysym.sym == SDLK_DOWN) dy++;
    if (event.key.keysym.sym == SDLK_x) rot--;
    if (event.key.keysym.sym == SDLK_c) rot++;
    break;

    case SDL_QUIT:
    running = 0;
    break;
    }
    }


    update(dx, dy, rot);

    draw();

    SDL_Flip(screen);
    SDL_Delay(10);
    }

    SDL_Quit();
    return 0;
    }