<repo_name>Glydion/tetris1<file_sep>/main.cpp
//******************************************
// Tetris - v1.0.0
// By: <NAME>. (Glydion)
//
// Start Date: Sunday July 8, 2018
// Finish Date:
//******************************************

#include "main.h"

int main( int argc, char* argv[] )
{
    // Create the game object
    Game* game = new Game();

    // Initialize and run the game
    if( game->Init() )
    {
        game->Run();
    }

    // Clean up
    delete game;

    return 0;
}
<file_sep>/Tetrimino.cpp
#include "Tetrimino.h"

Tetrimino::Tetrimino(SDL_Renderer* renderer)
{
    // Initialize data members
    this->renderer = renderer;

    // Initialize tile set spritesheet
    SDL_Surface* surface = IMG_Load("images/tiles.png");
    tileSet = SDL_CreateTextureFromSurface(renderer,surface);
    SDL_FreeSurface(surface);

    CreateShape();
}

Tetrimino::~Tetrimino()
{

}

void Tetrimino::CreateShape()
{
    int n = 3;

    //if(a[0].x == 0)
    //{
        for( int i = 0; i < 4; i++ )
        {
            a[i].x = figures[n][i] % 2;
            a[i].y = figures[n][i] / 2;
        }
    //}
}

void Tetrimino::RotatePiece()
{
    if(isRotating)
    {
        // Determine the center of rotation
        Point p = a[1];

        for(int i = 0; i < 4; i++)
        {
            int x = a[i].y - p.y;
            int y = a[i].x - p.x;
            a[i].x = p.x - x;
            a[i].y = p.y + y;
        }
    }
}

void Tetrimino::MovePiece()
{
    if(isMoving)
    {
        switch(moveDirection)
        {
            case -1:
            {
                for(int i = 0; i < 4; i++)
                {
                    a[i].x -= moveDirection;
                }
                break;
            }

            case 1:
            {
                for(int i = 0; i < 4; i++)
                {
                    a[i].x += moveDirection;
                }
                break;
            }

            case 2:
            {
                for(int i = 0; i < 4; i++)
                {
                    a[i].y += 1;
                }
            }
        }
    }
}

void Tetrimino::HandleEvent(SDL_Event& e)
{
    // If a key was pressed...
    if(e.type == SDL_KEYDOWN)
    {
        // Check which key was pressed
        switch(e.key.keysym.sym)
        {
            case SDLK_LEFT:
            {
                isMoving = true;
                moveDirection = -1;
                break;
            }

            case SDLK_RIGHT:
            {
                isMoving = true;
                moveDirection = 1;
                break;
            }

            case SDLK_DOWN:
            {
                isMoving = true;
                moveDirection = 2;
                break;
            }

            case SDLK_SPACE:
            {
                isRotating = true;
                break;
            }
        }
    }

    // If a key was released...
    else if(e.type == SDL_KEYUP)
    {
        switch(e.key.keysym.sym)
        {
            case SDLK_LEFT:
            {
                // Stop moving the Tetrimino left
                isMoving = false;
                moveDirection = 0;
                break;
            }

            case SDLK_RIGHT:
            {
                // Stop moving the Tetrimino right
                isMoving = false;
                moveDirection = 0;
                break;
            }

            case SDLK_DOWN:
            {
                isMoving = false;
                moveDirection = 0;
                break;
            }

            case SDLK_SPACE:
            {
                // Stop rotating the Tetrimino
                isRotating = false;
                break;
            }
        }
    }
}

void Tetrimino::Update(float delta)
{
    // Every frame, check to see whether
    // to move or rotate the Tetrimino (or both)
    this->RotatePiece();
    this->MovePiece();
}

void Tetrimino::Render(float delta)
{
    // Render all tiles of the tetrimino piece
    for( int i = 0; i < 4; i++ )
    {
        SDL_Rect srcRect;
        srcRect.x = 0;
        srcRect.y = 0;
        srcRect.w = CELL_WIDTH;
        srcRect.h = CELL_HEIGHT;

        // Set destination rectangle for each tile
        SDL_Rect dstRect;
        dstRect.x = a[i].x * CELL_WIDTH;
        dstRect.y = a[i].y * CELL_HEIGHT;
        dstRect.w = CELL_WIDTH;
        dstRect.h = CELL_HEIGHT;

        SDL_RenderCopy(renderer,tileSet,&srcRect,&dstRect);
    }
}
<file_sep>/Game.h
#ifndef GAME_H_
#define GAME_H_

// Preprocessors
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "SDL_mixer.h"
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <cmath>
#include <vector>

// Inclusions for game objects
#include "Tetrimino.h"

// Macros
#define FPS_DELAY       500
#define SCREEN_WIDTH    320
#define SCREEN_HEIGHT   480
#define GRID_WIDTH      10
#define GRID_HEIGHT     20


class Game
{
    public:
        Game();
        ~Game();

        bool Init();
        void Run();

    private:
        SDL_Window* window;
        SDL_Renderer* renderer;
        SDL_Texture* texture;

        // Game objects
        Tetrimino* testPiece;

        // Audio objects
        Mix_Music* gameMusic = NULL;

        // Timing
        unsigned int lastTick, fpsTick, fps, frameCount;

        // Font objects
        TTF_Font* fontScore;
        std::stringstream sValue;
        SDL_Texture* sTexture;
        int sWidth, sHeight;

        // Standard game functions
        void Clean();
        void Update(float delta);
        void Render(float delta);
        void NewGame();


};

#endif // GAME_H_
<file_sep>/Game.cpp
#include "Game.h"

Game::Game()
{
    window = 0;
    renderer = 0;
}

Game::~Game()
{

}

bool Game::Init()
{
    // Initialize the SDL video and audio subsystems
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    // Create window
    window = SDL_CreateWindow("Tetris v1.0", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                              SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL );

    if(!window)
    {
        std::cout << "Error creating window: " << SDL_GetError() << std::endl;
        return false;
    }

    // Create renderer
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if(!renderer)
    {
        std::cout << "Error creating renderer: " << SDL_GetError() << std::endl;
        return false;
    }

    // Enable TTF loading
    TTF_Init();

    // Load the fonts
    fontScore = TTF_OpenFont("Munro.ttf", 20);

    // Initialize SDL mixer
    if( Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0 )
    {
        std::cout << "Error initializing SDL mixer: " << Mix_GetError() << std::endl;
        return false;
    }

    // Load music
    gameMusic = Mix_LoadMUS("sounds/tetris.mp3");
    if( !gameMusic )
    {
        std::cout << "Error loading Tetris music: " << Mix_GetError() << std::endl;
        return false;
    }

    // Load sounds

    // Seed random number generation
    srand(time(0));

    // Initialize timing
    lastTick = SDL_GetTicks();
    fpsTick = lastTick;
    fps = 0;                    // Set starting FPS value
    frameCount = 0;             // Set starting frame count

    return true;
}

void Game::Clean()
{
    // Clean resources
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    Mix_FreeMusic(gameMusic);
    gameMusic = NULL;

    // Clean test data
    SDL_DestroyTexture(sTexture);
}

void Game::Run()
{
    // Create game objects
    testPiece = new Tetrimino(renderer);

    // Start the game music
    Mix_PlayMusic(gameMusic,-1);

    // Start a new game
    NewGame();

    // Main game loop
    while(1)
    {
        // Event handler
        SDL_Event e;

        // If event is a QUIT event, stop the program
        if(SDL_PollEvent(&e))
        {
            if(e.type == SDL_QUIT)
            {
                break;
            }

            // Handle input for the Tetrimino
            testPiece->HandleEvent(e);
        }

        // Calculate delta and fps
        unsigned int curTick = SDL_GetTicks();
        float delta = (curTick - lastTick) / 1000.0f;

        // Cap FPS delay to specific amount
        if(curTick - fpsTick > FPS_DELAY)
        {
            fps = frameCount * (1000.0f / (curTick - fpsTick));
            fpsTick = curTick;
            frameCount = 0;
            //std::cout << "FPS: " << fps << std::endl;
            char buf[100];
            snprintf(buf,100,"Tetris v1.0 (fps: %u)",fps);
            SDL_SetWindowTitle(window,buf);
        }
        else
        {
            frameCount++;
        }

        lastTick = curTick;

        // Update and render the game
        Update(delta);
        Render(delta);
    }

    delete testPiece;

    Clean();

    // Close the fonts
    TTF_CloseFont(fontScore);

    // Close all subsystems
    TTF_Quit();
    Mix_Quit();
    SDL_Quit();
}

void Game::NewGame()
{

}

void Game::Update(float delta)
{
    // Update the Tetrimino test piece
    testPiece->Update(delta);
}

void Game::Render(float delta)
{
    // Clear the renderer
    SDL_RenderClear(renderer);

    // Render the game objects
    testPiece->Render(delta);

    // Present the renderer to display
    SDL_RenderPresent(renderer);
}
<file_sep>/Tetrimino.h
#ifndef TETRIMINO_H_INCLUDED
#define TETRIMINO_H_INCLUDED

#define CELL_WIDTH 18
#define CELL_HEIGHT 18
#define MOVE_DISTANCE 18

#include "SDL.h"
#include "SDL_image.h"

class Tetrimino
{
    public:
        Tetrimino(SDL_Renderer* renderer);
        ~Tetrimino();

        // 2D array of pieces and their shapes
        int figures[7][4] =
        {
            {1,3,5,7},        // I
            {2,4,5,7},        // Z
            {3,5,4,6},        // S
            {3,5,4,7},        // T
            {2,3,5,7},        // L
            {3,5,7,6},        // J
            {2,3,4,5},        // O
        };

        struct Point
        {int x, y;} a[4], b[4];

        void CreateShape();

        void Update(float delta);
        void Render(float delta);

        void HandleEvent(SDL_Event& e);

        void RotatePiece();
        void MovePiece();

    private:
        SDL_Texture* tileSet;
        SDL_Renderer* renderer;

        bool isMoving;
        bool isRotating;
        int moveDirection;
};

#endif // TETRIMINO_H_INCLUDED
