<commit_before>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "message.h"
#include "segment.h"
#include "register_request_message.h"

using namespace std;

// Checks the number and formats of the environment variables passed
void checkEnvironmentVariables() {
   char* serverAddress = getenv("BINDER_ADDRESS");
   if (serverAddress == 0) {
      exit(-1);
   } // if

   char* serverPort = getenv("BINDER_PORT");
   if (serverPort == 0) {
      exit(-1);
   } // if
} // checkEnvironmentVariables

// Sets up the client socket
int setUpClientSocket() {
   struct addrinfo serverAddressHints;
   struct addrinfo* serverAddressResults;

   // Creates the client socket
   int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
   if (clientSocket < 0) {
      exit(-1);
   } // if

   // Gets the environment variables passed
   char* serverAddress = getenv("BINDER_ADDRESS");
   char* serverPort = getenv("BINDER_PORT");

   // Sets up the server address hints and results to perform the DNS
   // lookup on the server's host name to obtain the server's IP address
   memset(&serverAddressHints, 0, sizeof(serverAddressHints));
   serverAddressHints.ai_family = AF_INET;
   serverAddressHints.ai_socktype = SOCK_STREAM;

   // Performs a DNS lookup on the server's host name to obtain the
   // server's IP address
   int result = getaddrinfo(serverAddress, serverPort,
      &serverAddressHints, &serverAddressResults);
   if (result != 0) {
      exit(-1);
   } // if

   // Initiates the TCP connection between the client and the server
   result = connect(clientSocket, serverAddressResults->ai_addr,
      serverAddressResults->ai_addrlen);
   if (result < 0) {
      exit(-1);
   } // if

   // Frees up memory allocated for the server address results
   freeaddrinfo(serverAddressResults);

   return clientSocket;
} //setUpSocket

int main() {
   // Checks the number and formats of the environment variables passed
   checkEnvironmentVariables();

   // Sets up the client socket
   int clientSocket = setUpClientSocket();

   string serverIdentifier = "ubuntu1404-002.student.cs.uwaterloo.ca";
   unsigned int port = 80;
   string name = "func";
   int argTypes[3] = {1337, 2525, 369};
   RegisterRequestMessage msg = RegisterRequestMessage(serverIdentifier, port, name, argTypes);
   cout << "Server Identifier: " << msg.getServerIdentifier() << endl;
   cout << "Port: " << msg.getPort() << endl;
   cout << "Name: " << msg.getName() << endl;
   cout << "ArgTypes: " << *(msg.getArgTypes()) << ", " << *(msg.getArgTypes() + 1) << ", " << *(msg.getArgTypes() + 2) << ", " << *(msg.getArgTypes() + 3) << ", "  <<endl;
   Segment seg = Segment(msg.getLength(), MSG_TYPE_REGISTER_REQUEST, &msg);
   seg.send(clientSocket);

   // Closes the client socket

   sleep(2);

   close(clientSocket);
} // main
<commit_msg>changes<commit_after>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "message.h"
#include "segment.h"
#include "register_request_message.h"

using namespace std;

// Checks the number and formats of the environment variables passed
void checkEnvironmentVariables() {
   char* serverAddress = getenv("BINDER_ADDRESS");
   if (serverAddress == 0) {
      exit(-1);
   } // if

   char* serverPort = getenv("BINDER_PORT");
   if (serverPort == 0) {
      exit(-1);
   } // if
} // checkEnvironmentVariables

// Sets up the client socket
int setUpClientSocket() {
   struct addrinfo serverAddressHints;
   struct addrinfo* serverAddressResults;

   // Creates the client socket
   int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
   if (clientSocket < 0) {
      exit(-1);
   } // if

   // Gets the environment variables passed
   char* serverAddress = getenv("BINDER_ADDRESS");
   char* serverPort = getenv("BINDER_PORT");

   // Sets up the server address hints and results to perform the DNS
   // lookup on the server's host name to obtain the server's IP address
   memset(&serverAddressHints, 0, sizeof(serverAddressHints));
   serverAddressHints.ai_family = AF_INET;
   serverAddressHints.ai_socktype = SOCK_STREAM;

   // Performs a DNS lookup on the server's host name to obtain the
   // server's IP address
   int result = getaddrinfo(serverAddress, serverPort,
      &serverAddressHints, &serverAddressResults);
   if (result != 0) {
      exit(-1);
   } // if

   // Initiates the TCP connection between the client and the server
   result = connect(clientSocket, serverAddressResults->ai_addr,
      serverAddressResults->ai_addrlen);
   if (result < 0) {
      exit(-1);
   } // if

   // Frees up memory allocated for the server address results
   freeaddrinfo(serverAddressResults);

   return clientSocket;
} //setUpSocket

int main() {
   // Checks the number and formats of the environment variables passed
   checkEnvironmentVariables();

   // Sets up the client socket
   int clientSocket = setUpClientSocket();

   string serverIdentifier = "ubuntu1404-002.student.cs.uwaterloo.ca";
   unsigned int port = 80;
   string name = "func";
   /* prepare the arguments for f0 */
   int a0 = 5;
   int b0 = 10;
   int count0 = 3;
   int return0;
   int argTypes0[count0 + 1];
   void **args0;

   argTypes0[0] = (1 << ARG_OUTPUT) | (ARG_INT << 16);
   argTypes0[1] = (1 << ARG_INPUT) | (ARG_INT << 16);
   argTypes0[2] = (1 << ARG_INPUT) | (ARG_INT << 16);
   argTypes0[3] = 0;

   args0 = (void **)malloc(count0 * sizeof(void *));
   args0[0] = (void *)&return0;
   args0[1] = (void *)&a0;
   args0[2] = (void *)&b0;

   ExecuteRequestMessage msg = ExecuteRequestMessage(name, argTypes);
   //cout << "Server Identifier: " << msg.getServerIdentifier() << endl;
   //cout << "Port: " << msg.getPort() << endl;
   //cout << "Name: " << msg.getName() << endl;
   //cout << "ArgTypes: " << *(msg.getArgTypes()) << ", " << *(msg.getArgTypes() + 1) << ", " << *(msg.getArgTypes() + 2) << ", " << *(msg.getArgTypes() + 3) << ", "  <<endl;

   Segment seg = Segment(msg.getLength(), MSG_TYPE_EXECUTE_REQUEST, &msg);
   seg.send(clientSocket);

   // Closes the client socket

   sleep(2);

   close(clientSocket);
} // main
<|endoftext|>


<commit_before>#include "tui.h"
#include <assert.h>
#include <climits>

void Tui::add(std::shared_ptr<AComponent> const& c)
{
    if(std::dynamic_pointer_cast<Menu>(c)) {
        m_menus.push_back(c);
        return;
    }
    m_built.assign("");
    assert(m_current < m_ctrls.size());
    m_ctrls[m_current].push_back(c);
}

void Tui::ln()
{
    m_built.assign("");
    m_ctrls.resize(m_ctrls.size() + 1);
    m_current++;
}

void Tui::width(int const w)
{
    m_width = w;
}

int Tui::build()
{
    int max_width = m_width - 1 - 2;
    for(size_t i = 0; i < m_ctrls.size(); ++i) {
        int line_width = 3;
        ComponentDriver drv;
        drv.line = 0;
        if(m_ctrls[i].size() == 0) continue;
        drv.width = max_width / m_ctrls[i].size();
        drv.height = 1;
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int w = m_ctrls[i][j]->width(drv);
            if(w < 0) line_width++;
            else line_width += 1 + w;
        }
        if(line_width > max_width) max_width = line_width;
    }

    std::stringstream s;

    // title bar
    s << ' ' << std::string(max_width - 2, '_') << ' ' << std::endl;
    s << "|X|_" << m_name << std::string(max_width - 4 - m_name.size() - 4, '_') << "_|+|" << std::endl;
    //s << '|' << std::string(max_width - 2, '-') << '|' << std::endl;
    s << "|";
    int menuWidth = max_width - 1 - 2;
    ComponentDriver scratch01;
    for(std::vector<std::shared_ptr<AComponent> >::iterator i = m_menus.begin();
            i != m_menus.end(); ++i)
    {
        if(menuWidth < (*i)->width(scratch01)) break;
        s << '-';
        menuWidth -= 1 + (*i)->width(scratch01);
        s << (*i)->str(scratch01);
    }
    s << std::string(menuWidth, '-');
    s << "-|" << std::endl;

    for(size_t i = 0; i < m_ctrls.size(); ++i) {
        int max_height = 0;
        ComponentDriver drv;
        if(m_ctrls[i].size() == 0) {
            s << "|" << std::string(max_width - 2, ' ') << "|" << std::endl;
            continue;
        }
        drv.width = max_width / m_ctrls[i].size();
        drv.line = 0;
        drv.height = 1;
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int h = m_ctrls[i][j]->height(drv);
            if(h > max_height) max_height = h;
        }
        drv.height = max_height;

        // compute width of variable width components
        std::vector<int> widths(m_ctrls[i].size(), 0);
        float max_weight = 0.0f;
        int remaining = max_width - 3;
        bool haveVariableWidthComponents(false);
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            remaining--;
            int w = m_ctrls[i][j]->width(drv);
            if(w > 0) {
                widths[j] = w;
                remaining -= w;
            } else {
                max_weight += m_ctrls[i][j]->my_weight();
                haveVariableWidthComponents = true;
            }
        }
        int splitremaining = remaining;
        struct {
            size_t idx;
            int val;
        } min = { -1, INT_MAX };
        if(haveVariableWidthComponents)
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int w = m_ctrls[i][j]->width(drv);
            if(w <= 0) {
                widths[j] = splitremaining * m_ctrls[i][j]->my_weight() / max_weight;
                if(widths[j] < min.val) {
                    min.idx = j;
                    min.val = widths[j];
                }
                remaining -= widths[j];
            }
        }
        if(haveVariableWidthComponents && remaining) {
            widths[min.idx] += remaining;
            remaining = 0;
        }
        for(int h = 0; h < drv.height; ++h) {
            drv.line = h;
            s << "|";
            for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
                drv.width = widths[j];
                s << " " << m_ctrls[i][j]->str(drv);
            }
            if(remaining) {
                s << std::string(remaining, ' ');
            }
            s << " |" << std::endl;
        }
    }

    s << "|" << std::string(max_width - 2, '_') << "|" << std::endl;

    m_built.assign(s.str());

    return 0;
}

char const* const Tui::str() const
{
    return m_built.c_str();
}
<commit_msg>don't print menubar line if no menu entries are present<commit_after>#include "tui.h"
#include <assert.h>
#include <climits>

void Tui::add(std::shared_ptr<AComponent> const& c)
{
    if(std::dynamic_pointer_cast<Menu>(c)) {
        m_menus.push_back(c);
        return;
    }
    m_built.assign("");
    assert(m_current < m_ctrls.size());
    m_ctrls[m_current].push_back(c);
}

void Tui::ln()
{
    m_built.assign("");
    m_ctrls.resize(m_ctrls.size() + 1);
    m_current++;
}

void Tui::width(int const w)
{
    m_width = w;
}

int Tui::build()
{
    int max_width = m_width - 1 - 2;
    for(size_t i = 0; i < m_ctrls.size(); ++i) {
        int line_width = 3;
        ComponentDriver drv;
        drv.line = 0;
        if(m_ctrls[i].size() == 0) continue;
        drv.width = max_width / m_ctrls[i].size();
        drv.height = 1;
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int w = m_ctrls[i][j]->width(drv);
            if(w < 0) line_width++;
            else line_width += 1 + w;
        }
        if(line_width > max_width) max_width = line_width;
    }

    std::stringstream s;

    // title bar
    s << ' ' << std::string(max_width - 2, '_') << ' ' << std::endl;
    s << "|X|_" << m_name << std::string(max_width - 4 - m_name.size() - 4, '_') << "_|+|" << std::endl;
    //s << '|' << std::string(max_width - 2, '-') << '|' << std::endl;
    if(m_menus.size()) {
        s << "|";
        int menuWidth = max_width - 1 - 2;
        ComponentDriver scratch01;
        for(std::vector<std::shared_ptr<AComponent> >::iterator i = m_menus.begin();
                i != m_menus.end(); ++i)
        {
            if(menuWidth < (*i)->width(scratch01)) break;
            s << '-';
            menuWidth -= 1 + (*i)->width(scratch01);
            s << (*i)->str(scratch01);
        }
        s << std::string(menuWidth, '-');
        s << "-|" << std::endl;
    }/* else {
        s << '|' << std::string(max_width - 2, ' ') << '|' << std::endl;
    }*/

    for(size_t i = 0; i < m_ctrls.size(); ++i) {
        int max_height = 0;
        ComponentDriver drv;
        if(m_ctrls[i].size() == 0) {
            s << "|" << std::string(max_width - 2, ' ') << "|" << std::endl;
            continue;
        }
        drv.width = max_width / m_ctrls[i].size();
        drv.line = 0;
        drv.height = 1;
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int h = m_ctrls[i][j]->height(drv);
            if(h > max_height) max_height = h;
        }
        drv.height = max_height;

        // compute width of variable width components
        std::vector<int> widths(m_ctrls[i].size(), 0);
        float max_weight = 0.0f;
        int remaining = max_width - 3;
        bool haveVariableWidthComponents(false);
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            remaining--;
            int w = m_ctrls[i][j]->width(drv);
            if(w > 0) {
                widths[j] = w;
                remaining -= w;
            } else {
                max_weight += m_ctrls[i][j]->my_weight();
                haveVariableWidthComponents = true;
            }
        }
        int splitremaining = remaining;
        struct {
            size_t idx;
            int val;
        } min = { -1, INT_MAX };
        if(haveVariableWidthComponents)
        for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
            int w = m_ctrls[i][j]->width(drv);
            if(w <= 0) {
                widths[j] = splitremaining * m_ctrls[i][j]->my_weight() / max_weight;
                if(widths[j] < min.val) {
                    min.idx = j;
                    min.val = widths[j];
                }
                remaining -= widths[j];
            }
        }
        if(haveVariableWidthComponents && remaining) {
            widths[min.idx] += remaining;
            remaining = 0;
        }
        for(int h = 0; h < drv.height; ++h) {
            drv.line = h;
            s << "|";
            for(size_t j = 0; j < m_ctrls[i].size(); ++j) {
                drv.width = widths[j];
                s << " " << m_ctrls[i][j]->str(drv);
            }
            if(remaining) {
                s << std::string(remaining, ' ');
            }
            s << " |" << std::endl;
        }
    }

    s << "|" << std::string(max_width - 2, '_') << "|" << std::endl;

    m_built.assign(s.str());

    return 0;
}

char const* const Tui::str() const
{
    return m_built.c_str();
}
<|endoftext|>


<commit_before>#include <string>
#include <iostream>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Model
#include <boost/test/included/unit_test.hpp>

#include "../inc/model.hpp"
using namespace Model;

const quat<float> R0{0}, R1{1},
	  i{0,1}, j{0,0,1}, k{0,0,0,1};
const dual<float> E0{R0}, E1{R0, 1},
	  Ei = E1*i, Ej = E1*j, Ek = E1*k;

BOOST_AUTO_TEST_CASE(quaternions) {
	BOOST_CHECK_EQUAL(i*j, k);
	BOOST_CHECK_EQUAL(j*i,-k);
}

BOOST_AUTO_TEST_CASE(dual_quaternions) {
	BOOST_CHECK_EQUAL(E1*E1, E0);
}
<commit_msg>Began troubleshooting errors with test suites when *linking* (!) with Clang++.<commit_after>#include <string>
#include <iostream>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Model
#include <boost/test/included/unit_test.hpp>

#include "../inc/quat.hpp"
#include "../inc/dual.hpp"
#include "../inc/model.hpp"

using namespace Model;

const quat<float> R0{0}, R1{1},
	  i{0,1}, j{0,0,1}, k{0,0,0,1};
const dual<float> E0{R0}, E1{R0, 1},
	  Ei = E1*i, Ej = E1*j, Ek = E1*k;

BOOST_AUTO_TEST_CASE(quaternions) {
	BOOST_CHECK_EQUAL(i*j, k);
	BOOST_CHECK_EQUAL(j*i,-k);
}

BOOST_AUTO_TEST_CASE(dual_quaternions) {
	BOOST_CHECK_EQUAL(E1*E1, E0);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <cmath>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <algorithm>
using namespace std;

Base::~Base()
{
}<commit_msg>forgot to include header<commit_after>#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <cmath>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <algorithm>
using namespace std;

#include "Base.h"

Base::~Base()
{
}<|endoftext|>


<commit_before>//
// Created by JULIA BALAJAN on 3/12/2016.
//
#include <random>
#include <iostream>
#include <algorithm>
#include "Game.h"

uint8_t Game::get_next_block() {
    static std::mt19937 generator(std::random_device{}());
    std::uniform_int_distribution<int> distribution(0,cCoord::max_coordinates);
    int val;
    for (val = distribution(generator); val == prev_block; val = distribution(generator))
        ;
    return val;
}

uint8_t Game::get_color_value() {
    static std::mt19937 generator(std::random_device{}());
    std::uniform_int_distribution<int> distribution(0, 255);\
    return distribution(generator);
}

// Stores template for all the different tetris pieces
const cCoord Game::struct_coords[][cCoord::max_coordinates + 1] = {{
                                                  /* Row: 1 */ {0, 0}, {1, 0}, {2, 0},
                                                  /* Row: 2 */ {0, 1},
                                          },
                                          {
                                                  /* Row: 1 */ {0, 0}, {1, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1},
                                          },
                                          {
                                                  /* Row: 1 */ {0, 0},
                                                  /* Row: 2 */ {0, 1},
                                                  /* Row: 3 */ {0, 2},
                                                  /* Row: 4 */ {0, 3},
                                          },
                                          {
                                                  /* Row: 1 */         {1, 0}, {2, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1},
                                          },
                                          {
                                                  /* Row: 1 */         {1, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1}, {2, 1},
                                          }};

// Stores the origins coords for all the different tetris pieces
const cCoord Game::struct_origins[cCoord::max_coordinates + 1] = {
        /* L Shaped */      {0, 0},
        /* Square shaped */ {0, 0},
        /* Stick shaped */  {0, 0},
        /* Stair shaped */  {1, 0},
        /* T shaped */      {1, 1},
};

Game::Game() {
    create_block();
}

inline void Game::create_block() {
    structList.push_back(Structure(get_next_block()));
}

Structure& Game::get_last_block() {
    return *(structList.end() - 1);
}

bool Game::isGameOver() const {
    return gameOver;
}

std::vector<Structure>& Game::getStructList() {
    return structList;
}

void Game::set_draw_color(const Structure &s) {
    SDL_SetRenderDrawColor(ren, s.red, s.green, s.blue, SDL_ALPHA_OPAQUE);
}

void Game::init() {

    // Initialise SDL_ttf
    if (TTF_Init() == -1) {
        std::cout << "Unable to initialise SDL_ttf: " << SDL_GetError() << std::endl;
        exit(1);
    }

    // Create window
    win = SDL_CreateWindow("Tetris", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, SDL_WINDOW_SHOWN);
    if (win == nullptr) {
        std::cout << "Window error: " << SDL_GetError() << std::endl;
        exit(1);
    }

    // Create renderer
    ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
    if (ren == nullptr) {
        std::cout << "Renderer error: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow(win);
        exit(1);
    }

    // Create white background
    SDL_Rect screen;
    screen.x = 0;
    screen.y = 0;
    screen.w = screen_width;
    screen.h = screen_height;
    SDL_SetRenderDrawColor(ren, 255, 255, 255, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(ren, &screen);

    // Initialise font
    constexpr int font_size = 48;
    font = TTF_OpenFont("pixelated.ttf", font_size);
    if (font == nullptr) {
        std::cout << "Font Initialisation Error: " << SDL_GetError() << std::endl;
        cleanup();
        exit(1);
    }

}

void Game::draw () {
    SDL_SetRenderDrawColor(ren, 255, 255, 255, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(ren);
    SDL_Rect dest;
    dest.w = tile_size;
    dest.h = tile_size;

    int x,
        y;

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {

            // Cycle through x and y, if x and y match with block, draw block
            for (auto iter1 = structList.cbegin(); iter1 != structList.cend(); ++iter1)
                for (auto iter2 = iter1->coords.cbegin(); iter2 != iter1->coords.cend(); ++iter2)
                    if (x == iter2->get_x() && y == iter2->get_y()) {
                        set_draw_color(*iter1);
                        dest.x = x * tile_size;
                        dest.y = y * tile_size;
                        SDL_RenderFillRect(ren, &dest);
                        SDL_SetRenderDrawColor(ren, 0, 0, 0, SDL_ALPHA_OPAQUE);
                        SDL_RenderDrawRect(ren, &dest);
                        break;
                    }
        }
    }

    const SDL_Color color = {0, 0, 0};
    SDL_Surface *font_surf = TTF_RenderText_Blended(font, (std::string("Score: ") + std::to_string(score)).c_str(), color);
    if (font_surf == nullptr) {
        std::cout << "Font Rendering Error: " << SDL_GetError() << std::endl;
        TTF_CloseFont(font);
        cleanup();
        exit(1);
    }

    SDL_Texture *font_texture = SDL_CreateTextureFromSurface(ren, font_surf);
    if (font_texture == nullptr) {
        std::cout << "Create Font Texture Error: " << SDL_GetError() << std::endl;
        TTF_CloseFont(font);
        SDL_FreeSurface(font_surf);
        cleanup();
        exit(1);
    }

    SDL_FreeSurface(font_surf);

    constexpr int padding = 17;
    int w,
        h;
    SDL_QueryTexture(font_texture, nullptr, nullptr, &w, &h);
    dest.w = w;
    dest.h = h;
    dest.x = screen_width - w - padding;
    dest.y = 0 + padding;

    SDL_RenderCopy(ren, font_texture, nullptr, &dest);

    SDL_RenderPresent(ren);
}

void Game::cleanup() {
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();
}

void Game::controls (unsigned int &last_time) {
    unsigned long current_time = SDL_GetTicks();
    if ((current_time - last_time) > Game::wait_time_controls) {
        SDL_PollEvent(&events);
        if (events.type == SDL_KEYDOWN) {
            switch(events.key.keysym.sym) {
                case SDLK_UP :
                    get_last_block().rotate_left(structList);
                    break;
                case SDLK_DOWN :
                    get_last_block().rotate_right(structList);
                    break;
                case SDLK_LEFT :
                    get_last_block().move_left(structList);
                    break;
                case SDLK_RIGHT :
                    get_last_block().move_right(structList);
                    break;
                case SDLK_SPACE :
                    while(!get_last_block().move_down(structList))
                        ;
                    break;
                case SDLK_ESCAPE :
                    exit(0);
                    break;
            }
        }
        if(events.type == SDL_QUIT)
            gameOver = true;
        last_time = SDL_GetTicks();
    }
}

void Game::destroy() {
    bool fall_flag          = false;     // Flag to indicate whether the blocks should fall
    bool row_destroyed_flag = false;     // Flag indicating whether a row has been destroyed

    int row_to_destroy;         // Y value indicating the row to be destroyed
    int row_counter[height];    // Counter, to know which row to destroy
    int rows_been_destroyed = 0; // Count of how many rows have been destroyed to be used when calculating fall distance

    do {
        row_destroyed_flag = false;
        // Set the counter to 0
        std::fill(std::begin(row_counter), std::end(row_counter), 0);

        // Iterate through all the blocks, check if there are any complete rows, if so, destroy them
        for (auto &s : structList)
            for (auto &b : s.coords) {
                // If there is a complete row
                if (++row_counter[row_to_destroy = b.get_y()] >= width) {
                    // Destroy the blocks in the row
                    ++rows_been_destroyed;
                    for (auto &s : structList)
                        for (auto block_iter = s.coords.begin(); block_iter != s.coords.end();) {
                            if (block_iter->get_y() == row_to_destroy) {
                                block_iter = s.coords.erase(block_iter);
                                fall_flag = row_destroyed_flag = true;
                                continue;
                            }
                            ++block_iter;
                        }
                }
            }
    } while (row_destroyed_flag); // Re-iterate if a row was destroyed

    if (rows_been_destroyed <= 4)
        score += (100 * rows_been_destroyed);
    else if (rows_been_destroyed > 4)
        score += (200 * rows_been_destroyed);

    // If blocks have been destroyed, make the blocks above fall
    if (fall_flag) {
        // Iterate through the blocks, making the blocks above the destroyed row fall
        for (auto &s : structList)
            for (auto &b : s.coords)
                if (b.get_y() <= row_to_destroy)
                    b.move_down(rows_been_destroyed); // Fall by how many rows have been destroyed
    }
}

void Game::gameOverChecker() {
    if(structList.size() < 2)
        return;
    Structure block = *(structList.end() - 2);
    for (auto iter1 = block.coords.cbegin(); iter1 != block.coords.cend(); ++iter1) {
        if (iter1->get_y() <= 1) {
            gameOver = true;
            cleanup();
            return;
        }
    }
}

bool Game::collision_detector_y(int x, int y, std::vector<Structure> &structList) {
    for (auto i1 = structList.cbegin(); i1 != structList.end() - 1; ++i1)
        for (auto i2 = i1->coords.cbegin(); i2 != i1->coords.cend(); ++i2)
            if (i2->get_y() == y && i2->get_x() == x)
                return true;
    return false;
}

bool Game::collision_detector_x(int x, int y, std::vector<Structure> &structList) {
    for (auto i1 = structList.cbegin(); i1 != structList.end() - 1; ++i1)
        for (auto i2 = i1->coords.cbegin(); i2 != i1->coords.cend(); ++i2)
            if (i2->get_x() == x && i2->get_y() == y)
                return true;
    return false;
}

<commit_msg>Fixed destroy method once and for all<commit_after>//
// Created by JULIA BALAJAN on 3/12/2016.
//
#include <random>
#include <iostream>
#include <algorithm>
#include "Game.h"

uint8_t Game::get_next_block() {
    static std::mt19937 generator(std::random_device{}());
    std::uniform_int_distribution<int> distribution(0,cCoord::max_coordinates);
    int val;
    for (val = distribution(generator); val == prev_block; val = distribution(generator))
        ;
    return val;
}

uint8_t Game::get_color_value() {
    static std::mt19937 generator(std::random_device{}());
    std::uniform_int_distribution<int> distribution(0, 255);\
    return distribution(generator);
}

// Stores template for all the different tetris pieces
const cCoord Game::struct_coords[][cCoord::max_coordinates + 1] = {{
                                                  /* Row: 1 */ {0, 0}, {1, 0}, {2, 0},
                                                  /* Row: 2 */ {0, 1},
                                          },
                                          {
                                                  /* Row: 1 */ {0, 0}, {1, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1},
                                          },
                                          {
                                                  /* Row: 1 */ {0, 0},
                                                  /* Row: 2 */ {0, 1},
                                                  /* Row: 3 */ {0, 2},
                                                  /* Row: 4 */ {0, 3},
                                          },
                                          {
                                                  /* Row: 1 */         {1, 0}, {2, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1},
                                          },
                                          {
                                                  /* Row: 1 */         {1, 0},
                                                  /* Row: 2 */ {0, 1}, {1, 1}, {2, 1},
                                          }};

// Stores the origins coords for all the different tetris pieces
const cCoord Game::struct_origins[cCoord::max_coordinates + 1] = {
        /* L Shaped */      {0, 0},
        /* Square shaped */ {0, 0},
        /* Stick shaped */  {0, 0},
        /* Stair shaped */  {1, 0},
        /* T shaped */      {1, 1},
};

Game::Game() {
    create_block();
}

inline void Game::create_block() {
    structList.push_back(Structure(get_next_block()));
}

Structure& Game::get_last_block() {
    return *(structList.end() - 1);
}

bool Game::isGameOver() const {
    return gameOver;
}

std::vector<Structure>& Game::getStructList() {
    return structList;
}

void Game::set_draw_color(const Structure &s) {
    SDL_SetRenderDrawColor(ren, s.red, s.green, s.blue, SDL_ALPHA_OPAQUE);
}

void Game::init() {

    // Initialise SDL_ttf
    if (TTF_Init() == -1) {
        std::cout << "Unable to initialise SDL_ttf: " << SDL_GetError() << std::endl;
        exit(1);
    }

    // Create window
    win = SDL_CreateWindow("Tetris", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, SDL_WINDOW_SHOWN);
    if (win == nullptr) {
        std::cout << "Window error: " << SDL_GetError() << std::endl;
        exit(1);
    }

    // Create renderer
    ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
    if (ren == nullptr) {
        std::cout << "Renderer error: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow(win);
        exit(1);
    }

    // Create white background
    SDL_Rect screen;
    screen.x = 0;
    screen.y = 0;
    screen.w = screen_width;
    screen.h = screen_height;
    SDL_SetRenderDrawColor(ren, 255, 255, 255, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(ren, &screen);

    // Initialise font
    constexpr int font_size = 48;
    font = TTF_OpenFont("pixelated.ttf", font_size);
    if (font == nullptr) {
        std::cout << "Font Initialisation Error: " << SDL_GetError() << std::endl;
        cleanup();
        exit(1);
    }

}

void Game::draw () {
    SDL_SetRenderDrawColor(ren, 255, 255, 255, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(ren);
    SDL_Rect dest;
    dest.w = tile_size;
    dest.h = tile_size;

    int x,
        y;

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {

            // Cycle through x and y, if x and y match with block, draw block
            for (auto iter1 = structList.cbegin(); iter1 != structList.cend(); ++iter1)
                for (auto iter2 = iter1->coords.cbegin(); iter2 != iter1->coords.cend(); ++iter2)
                    if (x == iter2->get_x() && y == iter2->get_y()) {
                        set_draw_color(*iter1);
                        dest.x = x * tile_size;
                        dest.y = y * tile_size;
                        SDL_RenderFillRect(ren, &dest);
                        SDL_SetRenderDrawColor(ren, 0, 0, 0, SDL_ALPHA_OPAQUE);
                        SDL_RenderDrawRect(ren, &dest);
                        break;
                    }
        }
    }

    const SDL_Color color = {0, 0, 0};
    SDL_Surface *font_surf = TTF_RenderText_Blended(font, (std::string("Score: ") + std::to_string(score)).c_str(), color);
    if (font_surf == nullptr) {
        std::cout << "Font Rendering Error: " << SDL_GetError() << std::endl;
        TTF_CloseFont(font);
        cleanup();
        exit(1);
    }

    SDL_Texture *font_texture = SDL_CreateTextureFromSurface(ren, font_surf);
    if (font_texture == nullptr) {
        std::cout << "Create Font Texture Error: " << SDL_GetError() << std::endl;
        TTF_CloseFont(font);
        SDL_FreeSurface(font_surf);
        cleanup();
        exit(1);
    }

    SDL_FreeSurface(font_surf);

    constexpr int padding = 17;
    int w,
        h;
    SDL_QueryTexture(font_texture, nullptr, nullptr, &w, &h);
    dest.w = w;
    dest.h = h;
    dest.x = screen_width - w - padding;
    dest.y = 0 + padding;

    SDL_RenderCopy(ren, font_texture, nullptr, &dest);

    SDL_RenderPresent(ren);
}

void Game::cleanup() {
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();
}

void Game::controls (unsigned int &last_time) {
    unsigned long current_time = SDL_GetTicks();
    if ((current_time - last_time) > Game::wait_time_controls) {
        SDL_PollEvent(&events);
        if (events.type == SDL_KEYDOWN) {
            switch(events.key.keysym.sym) {
                case SDLK_UP :
                    get_last_block().rotate_left(structList);
                    break;
                case SDLK_DOWN :
                    get_last_block().rotate_right(structList);
                    break;
                case SDLK_LEFT :
                    get_last_block().move_left(structList);
                    break;
                case SDLK_RIGHT :
                    get_last_block().move_right(structList);
                    break;
                case SDLK_SPACE :
                    while(!get_last_block().move_down(structList))
                        ;
                    break;
                case SDLK_ESCAPE :
                    exit(0);
                    break;
            }
        }
        if(events.type == SDL_QUIT)
            gameOver = true;
        last_time = SDL_GetTicks();
    }
}

void Game::destroy() {
    bool fall_flag          = false;     // Flag to indicate whether the blocks should fall
    bool row_destroyed_flag = false;     // Flag indicating whether a row has been destroyed

    int row_to_destroy;         // Y value indicating the row to be destroyed
    std::vector<int> row_counter(height);    // Counter, to know which row to destroy
    int rows_been_destroyed = 0; // Count of how many rows have been destroyed to be used when calculating fall distance

    do {
        row_destroyed_flag = false;
        // Set the counter to 0

        // Iterate through all the blocks, check if there are any complete rows, if so, destroy them
        for (auto &s : structList)
            for (auto &b : s.coords) {
                // If there is a complete row
                if (++(row_counter[b.get_y()]) >= width) {
                    row_to_destroy = b.get_y();
                    std::cerr << "Counter: " << row_counter[row_to_destroy] << '\n';
                    std::fill(row_counter.begin(), row_counter.end(), 0);
                    // Destroy the blocks in the row
                    ++rows_been_destroyed;
                    for (auto &s : structList)
                        for (auto block_iter = s.coords.begin(); block_iter != s.coords.end();) {
                            if (block_iter->get_y() == row_to_destroy) {
                                std::cerr << row_to_destroy << '\n';
                                block_iter = s.coords.erase(block_iter);
                                fall_flag = row_destroyed_flag = true;
                                continue;
                            }
                            ++block_iter;
                        }
                }
            }
    } while (row_destroyed_flag); // Re-iterate if a row was destroyed

    if (rows_been_destroyed <= 4)
        score += (100 * rows_been_destroyed);
    else if (rows_been_destroyed > 4)
        score += (200 * rows_been_destroyed);

    // If blocks have been destroyed, make the blocks above fall
    if (fall_flag) {
        // Iterate through the blocks, making the blocks above the destroyed row fall
        for (auto &s : structList)
            for (auto &b : s.coords)
                if (b.get_y() < row_to_destroy) {
                    b.move_down(rows_been_destroyed); // Fall by how many rows have been destroyed
                }
    }
}

void Game::gameOverChecker() {
    if(structList.size() < 2)
        return;
    Structure block = *(structList.end() - 2);
    for (auto iter1 = block.coords.cbegin(); iter1 != block.coords.cend(); ++iter1) {
        if (iter1->get_y() <= 1) {
            gameOver = true;
            cleanup();
            return;
        }
    }
}

bool Game::collision_detector_y(int x, int y, std::vector<Structure> &structList) {
    for (auto i1 = structList.cbegin(); i1 != structList.end() - 1; ++i1)
        for (auto i2 = i1->coords.cbegin(); i2 != i1->coords.cend(); ++i2)
            if (i2->get_y() == y && i2->get_x() == x)
                return true;
    return false;
}

bool Game::collision_detector_x(int x, int y, std::vector<Structure> &structList) {
    for (auto i1 = structList.cbegin(); i1 != structList.end() - 1; ++i1)
        for (auto i2 = i1->coords.cbegin(); i2 != i1->coords.cend(); ++i2)
            if (i2->get_x() == x && i2->get_y() == y)
                return true;
    return false;
}

<|endoftext|>


<commit_before>//Lab 6
//modified from http://learnopengl.com/
#include <ctime>
#include "stdafx.h"

#include "..\glew\glew.h"	// include GL Extension Wrangler
#include "..\glfw\glfw3.h"	// include GLFW helper library
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <vector>

#include <fstream>
#include "glm.hpp"
#include "gtc/matrix_transform.hpp"
#include "gtc/type_ptr.hpp"
#include "Building.h"
#include <..\COMP371_Lab7\objloader.hpp>
#include "..\soil\SOIL.h"

using namespace std;

// Window dimensions
const GLuint WINDOW_WIDTH = 1000, WINDOW_HEIGHT = 1000;
const GLfloat CAMERA_MOVEMENT_STEP = 2.20f;
const float ANGLE_ROTATION_STEP = 0.15f;

glm::vec3 camera_position;
glm::mat4 projection_matrix;

//Declaring global array
vector<glm::vec3> vecBuildingCoordinate;	//coordinate of the building
vector<glm::vec3> vecBuildingSize;			//building size
vector<glm::vec3> vecBuildingColor;		//building color
vector<glm::vec3> vecMapCoordinate;		//coordinate of the new maps (for procedural generator)

//Declaring the method signature
glm::vec3 createBuilding();
glm::vec3 createCoordinate();
glm::vec3 createColor();
float randomFloat(float a, float b);

float y_rotation_angle = 0.0f, x_rotation_angle = 0.0f;

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	glViewport(0, 0, width, height);

	// Update the Projection matrix after a window resize event
	projection_matrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 1000.0f);
}

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
	std::cout << key << std::endl;
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
		glfwSetWindowShouldClose(window, GL_TRUE);

	if (key == GLFW_KEY_W && action == GLFW_PRESS)
		camera_position.z += CAMERA_MOVEMENT_STEP;

	if (key == GLFW_KEY_S && action == GLFW_PRESS)
		camera_position.z -= CAMERA_MOVEMENT_STEP;

	if (key == GLFW_KEY_A && action == GLFW_PRESS)
		camera_position.x -= CAMERA_MOVEMENT_STEP;

	if (key == GLFW_KEY_D && action == GLFW_PRESS)
		camera_position.x += CAMERA_MOVEMENT_STEP;

	//rotate cube
	if (key == GLFW_KEY_DOWN && action == GLFW_PRESS)
		x_rotation_angle += ANGLE_ROTATION_STEP;

	if (key == GLFW_KEY_UP && action == GLFW_PRESS)
		x_rotation_angle -= ANGLE_ROTATION_STEP;

	if (key == GLFW_KEY_RIGHT && action == GLFW_PRESS)
		y_rotation_angle += ANGLE_ROTATION_STEP;

	if (key == GLFW_KEY_LEFT && action == GLFW_PRESS)
		y_rotation_angle -= ANGLE_ROTATION_STEP;
}

GLuint loadCubemap(vector<const GLchar*> faces)
{
	GLuint textureID;
	glGenTextures(1, &textureID);

	int width, height;
	unsigned char* image;

	glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
	for (GLuint i = 0; i < faces.size(); i++)
	{
		image = SOIL_load_image(faces[i], &width, &height, 0, SOIL_LOAD_RGB);
		glTexImage2D(
			GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
			GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image
		);

		SOIL_free_image_data(image); //free resources
	}
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

	return textureID;
}

int main()
{
	srand(time(0)); //random number generator seed
	std::cout << "Starting Project Team 2" << std::endl;
	// Init GLFW
	glfwInit();
	// Set all the required options for GLFW
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_SAMPLES, 8);
	glEnable(GL_MULTISAMPLE);

	// Create a GLFWwindow object that we can use for GLFW's functions
	GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Cubemaps", nullptr, nullptr);
	if (window == nullptr)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	// Set the required callback functions
	glfwSetKeyCallback(window, key_callback);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
	glewExperimental = GL_TRUE;
	// Initialize GLEW to setup the OpenGL Function pointers
	if (glewInit() != GLEW_OK)
	{
		std::cout << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// Define the viewport dimensions
	int width, height;
	glfwGetFramebufferSize(window, &width, &height);

	glViewport(0, 0, width, height);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	projection_matrix = glm::perspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 1000.0f);

	// Build and compile our shader program
	// Vertex shader

	// Read the Vertex Shader code from the file
	string vertex_shader_path = "vertex.shader";
	string VertexShaderCode;
	std::ifstream VertexShaderStream(vertex_shader_path, ios::in);

	if (VertexShaderStream.is_open()) {
		string Line = "";
		while (getline(VertexShaderStream, Line))
			VertexShaderCode += "\n" + Line;
		VertexShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory ?\n", vertex_shader_path.c_str());
		getchar();
		exit(-1);
	}

	// Read the Fragment Shader code from the file
	string fragment_shader_path = "fragment.shader";
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream(fragment_shader_path, std::ios::in);

	if (FragmentShaderStream.is_open()) {
		std::string Line = "";
		while (getline(FragmentShaderStream, Line))
			FragmentShaderCode += "\n" + Line;
		FragmentShaderStream.close();
	}
	else {
		printf("Impossible to open %s. Are you in the right directory?\n", fragment_shader_path.c_str());
		getchar();
		exit(-1);
	}

	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
	char const * VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(vertexShader, 1, &VertexSourcePointer, NULL);
	glCompileShader(vertexShader);
	// Check for compile time errors
	GLint success;
	GLchar infoLog[512];
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Fragment shader
	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	char const * FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(fragmentShader, 1, &FragmentSourcePointer, NULL);
	glCompileShader(fragmentShader);
	// Check for compile time errors
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
	if (!success)
	{
		glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
	}
	// Link shaders
	GLuint shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);
	// Check for linking errors
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
	if (!success) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
		std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
	}
	glDeleteShader(vertexShader); //free up memory
	glDeleteShader(fragmentShader);

	glUseProgram(shaderProgram);

	std::vector<glm::vec3> vertices;
	std::vector<glm::vec3> normals;
	std::vector<glm::vec2> UVs;

	loadOBJ("cube.obj", vertices, normals, UVs);

	GLuint VAO, vertices_VBO, normals_VBO, UVs_VBO;

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &vertices_VBO);

	// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, vertices_VBO);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(0);

	glGenBuffers(1, &normals_VBO);
	glBindBuffer(GL_ARRAY_BUFFER, normals_VBO);
	glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(1);

	glGenBuffers(1, &UVs_VBO);
	glBindBuffer(GL_ARRAY_BUFFER, UVs_VBO);
	glBufferData(GL_ARRAY_BUFFER, UVs.size() * sizeof(glm::vec2), &UVs.front(), GL_STATIC_DRAW);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(2);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0);

	GLuint projectionLoc = glGetUniformLocation(shaderProgram, "projection_matrix");
	GLuint viewMatrixLoc = glGetUniformLocation(shaderProgram, "view_matrix");
	GLuint transformLoc = glGetUniformLocation(shaderProgram, "model_matrix");

	GLuint drawing_skybox_id = glGetUniformLocation(shaderProgram, "drawingSkybox");

	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

	glActiveTexture(GL_TEXTURE0); //select texture unit 0

	GLuint cube_texture;
	glGenTextures(1, &cube_texture);
	glBindTexture(GL_TEXTURE_2D, cube_texture); //bind this texture to the currently bound texture unit

												// Set the texture wrapping parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

	// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	// Set texture filtering parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// Load image, create texture and generate mipmaps
	int cube_texture_width, cube_texture_height;
	unsigned char* cube_image = SOIL_load_image("window2.jpg", &cube_texture_width, &cube_texture_height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, cube_texture_width, cube_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, cube_image);

	SOIL_free_image_data(cube_image); //free resources

	unsigned char* top_image = SOIL_load_image("grass.jpg", &cube_texture_width, &cube_texture_height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 10, GL_RGB, cube_texture_width, cube_texture_height, 10, GL_RGB, GL_UNSIGNED_BYTE, top_image);
	SOIL_free_image_data(top_image); //free resources

	//Setup our cubemap

	vector<const GLchar*> faces;
	faces.push_back("cube_map/a.jpg");	//right
	faces.push_back("cube_map/c.jpg");	// left
	faces.push_back("cube_map/top.jpg");	// top
	faces.push_back("cube_map/bottom.jpg");	// bottom
	faces.push_back("cube_map/b.jpg");	// back
	faces.push_back("cube_map/d.jpg");	// front

	glActiveTexture(GL_TEXTURE1);
	GLuint cubemapTexture = loadCubemap(faces);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);

	glUniform1i(glGetUniformLocation(shaderProgram, "cubeTexture"), 0); //cubeTexture should read from texture unit 0
	glUniform1i(glGetUniformLocation(shaderProgram, "skybox"), 1); //sky box should read from texture unit 1
	glUniform1i(glGetUniformLocation(shaderProgram, "grassTexture"), 10); //cubeTexture should read from texture unit 2

	//create 10 buildings
	for (int i = 0; i < 1000; i++) {
		createBuilding();
		createCoordinate();
		cout << "Create buildings " << endl;
		cout << "Map of Coordinate : " << vecMapCoordinate.size() << endl;
		cout << "Number of build : " << vecBuildingSize.size() << endl;
		if (i == 10) {
			vecBuildingCoordinate.push_back(glm::vec3(0, -1, 0));
			vecBuildingSize.push_back(glm::vec3(100, 0.5, 100));
		}
	}

	while (!glfwWindowShouldClose(window))
	{
		glfwPollEvents();
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glm::mat4 model_matrix;
		model_matrix = glm::rotate(model_matrix, y_rotation_angle, glm::vec3(0.0f, 1.0f, 0.0f));
		model_matrix = glm::rotate(model_matrix, x_rotation_angle, glm::vec3(1.0f, 0.0f, 0.0f));

		glm::mat4 view_matrix;
		view_matrix = translate(view_matrix, camera_position);

		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));			// Model
		glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection_matrix));		// The pespective
		glBindVertexArray(VAO);

		//Draw the skybox

		glm::mat4 skybox_view = glm::mat4(glm::mat3(view_matrix)); //remove the translation data
		glUniformMatrix4fv(viewMatrixLoc, 1, GL_FALSE, glm::value_ptr(skybox_view));

		glDepthMask(GL_FALSE);

		glUniform1i(drawing_skybox_id, 1); //set the uniform boolean
		glDrawArrays(GL_TRIANGLES, 0, vertices.size());

		glDepthMask(GL_TRUE);

		//Draw the textured cube

		// Plane and one block

				glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
				glUniformMatrix4fv(viewMatrixLoc, 1, GL_FALSE, glm::value_ptr(view_matrix));
				glUniform1i(drawing_skybox_id, 0); //set the boolean
				glDrawArrays(GL_TRIANGLES, 0, vertices.size());

		//glBindVertexArray(VAO);
		//cout << vecMapCoordinate.size() << endl;
				glm::mat4 model_building;
		for (GLuint i = 0; i < vecBuildingCoordinate.size(); i++) {
			//cout << "im currentoy to draw " << vecBuildingCoordinate.size() << " cubes. " << endl;

			model_matrix = glm::translate(model_matrix, vecBuildingCoordinate[i]);
			model_matrix = glm::scale(model_matrix, vecBuildingSize[i]);
			glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
			//glUniformMatrix4fv(viewMatrixLoc, 1, GL_FALSE, glm::value_ptr(view_matrix));
		//	glUniform1i(drawing_skybox_id, 0); //set the boolean
			glDrawArrays(GL_TRIANGLES, 0, vertices.size());

		}

		glBindVertexArray(0);

		// Swap the screen buffers
		glfwSwapBuffers(window);
	}

	glfwTerminate();
	return 0;
}
/*
Method : CreateBuilding()
Return a random size of building
*/
glm::vec3 createBuilding() {

	float width = randomFloat(1, 2);	// x
	float height = randomFloat(1,2);	// y
	float depth = randomFloat(1,2);		// z

	cout << "WIDTH = " << width << endl;
	cout << "depth = " << depth << endl;
	cout << "height = " << height << endl;

	glm::vec3 sizeScale = glm::vec3(width, height, depth);
	vecBuildingSize.push_back(sizeScale);

	return sizeScale;

}
glm::vec3 createColor() {

	float R = rand() % 4;
	float G = rand() % 4;
	float B = rand() % 4;

	cout << "R = " << R << endl;
	cout << "G = " << G << endl;
	cout << "B = " << B << endl;

	vecBuildingColor.push_back(glm::vec3(R, G, B));
	glm::vec3 color = glm::vec3(R, G, B);
	return color;
}

glm::vec3 createCoordinate() {

	float coox = randomFloat(-50,50);
	float cooz = randomFloat(-50, 50);
	cout << "coox = " << coox << endl;
	cout << "cooz = " << cooz << endl;

	glm::vec3 coordinate = glm::vec3(coox, 0, cooz);
	vecBuildingCoordinate.push_back(coordinate);
	return coordinate;

}
float randomFloat(float a, float b) {
	float random = ((float)rand()) / (float)RAND_MAX;
	float diff = b - a;
	float r = random * diff;
	return a + r;
}<commit_msg>Delete Lab7.cpp<commit_after><|endoftext|>


<commit_before>#include <QGLWidget>
#include "Mesh.h"
#include "Matrix44.h"
#include "Common.h"

Mesh::Mesh() : triangleColouring(MESH_COLOUR_SAME), geomType(MESH_GEOM_TRIANGLES),
	surfaceTexture(NULL), useSurfaceNormals(false)
{
}

Mesh::~Mesh()
{
}

const VertexList& Mesh::vertices() const
{
	return verts;
}

void Mesh::setVertices(const VertexList& newVerts)
{
	verts = newVerts;
}

const TriangleList& Mesh::triangles() const
{
	return tris;
}

void Mesh::setTriangles(const TriangleList& newTris)
{
	tris = newTris;
}

Mesh::Colouring Mesh::colouring() const
{
	return triangleColouring;
}

void Mesh::setColouring(Mesh::Colouring newColouring)
{
	triangleColouring = newColouring;
}

Mesh::GeometryType Mesh::geometryType() const
{
	return geomType;
}

void Mesh::setGeometryType(Mesh::GeometryType newGeomType)
{
	geomType = newGeomType;
}

bool Mesh::showingNormals() const
{
	return drawNormals;
}

void Mesh::showNormals(bool willShow)
{
	drawNormals = willShow;
}

Texture* Mesh::texture() const
{
	return surfaceTexture;
}

void Mesh::setTexture(Texture* newTexture)
{
	surfaceTexture = newTexture;
}

bool Mesh::usingPerFaceNormals() const
{
	return useSurfaceNormals;
}

void Mesh::setPerFaceNormals(bool usePerFace)
{
	useSurfaceNormals = usePerFace;
}

void Mesh::renderVertex(const Vertex& v)
{
	glTexCoord2f(v.texCoord.s, v.texCoord.t);
	glNormal3f(v.normal.x, v.normal.y, v.normal.z);
	glVertex3f(v.position.x, v.position.y, v.position.y);
}

void Mesh::renderTriangle(const VertexList& verticesToUse, const Triangle& tri)
{
	renderVertex( verticesToUse[tri.v1] );
	renderVertex( verticesToUse[tri.v2] );
	renderVertex( verticesToUse[tri.v3] );
}

void Mesh::renderPoints(const VertexList& vertices)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_POINTS);
		for (VertexList::const_iterator it = vertices.begin(); (it != vertices.end()); it++)
			glVertex3f(it->position.x, it->position.y, it->position.x);
	glEnd();
}

void Mesh::renderLines(const VertexList& vertices, const TriangleList& triangles)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_LINES);
		for (TriangleList::const_iterator it = triangles.begin(); (it != triangles.end()); it++)
		{
			const Vertex& v1 = vertices[it->v1];
			const Vertex& v2 = vertices[it->v2];
			const Vertex& v3 = vertices[it->v3];
			glVertex3f(v1.position.x, v1.position.y, v1.position.x);
			glVertex3f(v2.position.x, v2.position.y, v2.position.x);
			glVertex3f(v2.position.x, v2.position.y, v2.position.x);
			glVertex3f(v3.position.x, v3.position.y, v3.position.x);
			glVertex3f(v3.position.x, v3.position.y, v3.position.x);
			glVertex3f(v1.position.x, v1.position.y, v1.position.x);
		}
	glEnd();
}

void Mesh::renderTriangles(const VertexList& vertices, const TriangleList& triangles)
{
	glBegin(GL_TRIANGLES);
	if (triangleColouring == MESH_ALTERNATING_TRIANGLES)
	{
		// Whole for-loop put it if-statement so there isn't a branch every iteration (costly operation
		for (unsigned int i = 0; (i < triangles.size()); i++)
		{
			const Vector3& col = ALTERNATING_TRIANGLE_COLOURS[i % NUM_ALTERNATING_COLOURS];
			glColor3f(col.x, col.y, col.y);
			renderTriangle(vertices, tris[i]);
		}
	}
	else
	{
		for (TriangleList::const_iterator it = triangles.begin(); (it != triangles.end()); it++)
			renderTriangle(vertices, *it);
	}
	glEnd();
}

void Mesh::renderNormals(const VertexList& vertices)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_LINES);
		for (VertexList::const_iterator it = vertices.begin(); (it != vertices.end()); it++)
		{
			const Vector3& position = it->position;
			const Vector3& normal = it->normal;
			Vector3 end = position + (normal * NORMAL_SCALING_FACTOR);
			glVertex3f(it->position.x, it->position.y, it->position.z);
			glVertex3f(end.x, end.y, end.y);
		}
	glEnd();
}

/* Draw a torus */
#include <math.h>
static void torus(int numc, int numt)
{
   int i, j, k;
   double s, t, x, y, z, twopi;

   twopi = 2 * (double)M_PI;
   for (i = 0; i < numc; i++) {
      glBegin(GL_QUAD_STRIP);
      for (j = 0; j <= numt; j++) {
         for (k = 1; k >= 0; k--) {
            s = (i + k) % numc + 0.5;
            t = j % numt;

            x = (1+.1*cos(s*twopi/numc))*cos(t*twopi/numt);
            y = (1+.1*cos(s*twopi/numc))*sin(t*twopi/numt);
            z = .1 * sin(s * twopi / numc);

                        const Vector3& col = ALTERNATING_TRIANGLE_COLOURS[(i * j) % NUM_ALTERNATING_COLOURS];
                       glColor3f(col.x, col.y, col.y);

            glVertex3f(x, y, z);
         }
      }
      glEnd();
   }
}

void Mesh::render()
{
	/*MatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glRotatef(rot.x, 1.0f, 0.0f, 0.0f);
	glRotatef(rot.y, 0.0f, 1.0f, 0.0f);
	glRotatef(rot.z, 0.0f, 0.0f, 1.0f);
	torus(8, 8);
	glPopMatrix();
	return;*/

	// If texturing has been enabled, ensure we set the correct OpenGL state
	if (triangleColouring == MESH_TEXTURE)
	{
		// If texture hasn't been loaded yet - load it now!
		// This is lazy initialisation
		if (!surfaceTexture)
			surfaceTexture = new Texture("resources/world_texture.jpg");
		glEnable(GL_TEXTURE_2D);
		surfaceTexture->bind();
	}

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	// Perform local model transformations on mesh
	Matrix44 transformation =  Matrix44::translation(pos.x, pos.y, pos.z);
	transformation = transformation * Matrix44::xyzRotation(rot);
	// Transform vertices using position and orientation of drawable
	VertexList transformedVerts = verts;
	// If using per-face normals and not per-vertex normals, compute surface normals now
	if (useSurfaceNormals)
	{
		Vector3List surfaceNormals = computeSurfaceNormals(transformedVerts, tris);
		for (int i = 0; (i < surfaceNormals.size()); i++)
		{
			transformedVerts[i].normal = surfaceNormals[i];
		}
	}
	for (VertexList::iterator it = transformedVerts.begin(); (it != transformedVerts.end()); it++)
	{
		it->position = transformation * it->position;
		it->normal = (transformation * it->normal).normalise();
	}

	// How mesh is drawn depends on geometry type chosen
	switch (geomType)
	{
	case MESH_GEOM_POINTS:
		renderPoints(transformedVerts);
		break;
	case MESH_GEOM_LINES:
		renderLines(transformedVerts, tris);
		break;
	case MESH_GEOM_TRIANGLES:
		renderTriangles(transformedVerts, tris);
		break;
	}
	// Also draw lines reprensenting vertex normals
	if (drawNormals)
	{
		renderNormals(transformedVerts);
	}

	glPopMatrix();

	// Make sure the mesh's texture is unbinded after rendering
	if (triangleColouring == MESH_TEXTURE)
	{
		if (surfaceTexture)
			surfaceTexture->unbind();
		glDisable(GL_TEXTURE_2D);
	}
}

Vector3List Mesh::computeSurfaceNormals(const VertexList& vertices, const TriangleList& triangles)
{
	Vector3List normals;
	normals.resize(vertices.size());

	for (TriangleList::const_iterator it = triangles.begin();
		(it != triangles.end()); it++)
	{
		// Get two points of the triangle and create two vectors from them (sides of triangle)
		Vector3 s1 = vertices[it->v2].position - vertices[it->v1].position;
		Vector3 s2 = vertices[it->v3].position - vertices[it->v1].position;
		// Compute cross product of sides to get surface normal
		Vector3 surfaceNormal = s1.cross(s2).negate().normalise();
		// Assign this surface normal to all v
		normals[it->v1] = surfaceNormal;
		normals[it->v2] = surfaceNormal;
		normals[it->v3] = surfaceNormal;
	}

	return normals;
}
<commit_msg>Fixsed freverse normals for flat shading sphere<commit_after>#include <QGLWidget>
#include "Mesh.h"
#include "Matrix44.h"
#include "Common.h"

Mesh::Mesh() : triangleColouring(MESH_COLOUR_SAME), geomType(MESH_GEOM_TRIANGLES),
	surfaceTexture(NULL), useSurfaceNormals(false)
{
}

Mesh::~Mesh()
{
}

const VertexList& Mesh::vertices() const
{
	return verts;
}

void Mesh::setVertices(const VertexList& newVerts)
{
	verts = newVerts;
}

const TriangleList& Mesh::triangles() const
{
	return tris;
}

void Mesh::setTriangles(const TriangleList& newTris)
{
	tris = newTris;
}

Mesh::Colouring Mesh::colouring() const
{
	return triangleColouring;
}

void Mesh::setColouring(Mesh::Colouring newColouring)
{
	triangleColouring = newColouring;
}

Mesh::GeometryType Mesh::geometryType() const
{
	return geomType;
}

void Mesh::setGeometryType(Mesh::GeometryType newGeomType)
{
	geomType = newGeomType;
}

bool Mesh::showingNormals() const
{
	return drawNormals;
}

void Mesh::showNormals(bool willShow)
{
	drawNormals = willShow;
}

Texture* Mesh::texture() const
{
	return surfaceTexture;
}

void Mesh::setTexture(Texture* newTexture)
{
	surfaceTexture = newTexture;
}

bool Mesh::usingPerFaceNormals() const
{
	return useSurfaceNormals;
}

void Mesh::setPerFaceNormals(bool usePerFace)
{
	useSurfaceNormals = usePerFace;
}

void Mesh::renderVertex(const Vertex& v)
{
	glTexCoord2f(v.texCoord.s, v.texCoord.t);
	glNormal3f(v.normal.x, v.normal.y, v.normal.z);
	glVertex3f(v.position.x, v.position.y, v.position.y);
}

void Mesh::renderTriangle(const VertexList& verticesToUse, const Triangle& tri)
{
	renderVertex( verticesToUse[tri.v1] );
	renderVertex( verticesToUse[tri.v2] );
	renderVertex( verticesToUse[tri.v3] );
}

void Mesh::renderPoints(const VertexList& vertices)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_POINTS);
		for (VertexList::const_iterator it = vertices.begin(); (it != vertices.end()); it++)
			glVertex3f(it->position.x, it->position.y, it->position.x);
	glEnd();
}

void Mesh::renderLines(const VertexList& vertices, const TriangleList& triangles)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_LINES);
		for (TriangleList::const_iterator it = triangles.begin(); (it != triangles.end()); it++)
		{
			const Vertex& v1 = vertices[it->v1];
			const Vertex& v2 = vertices[it->v2];
			const Vertex& v3 = vertices[it->v3];
			glVertex3f(v1.position.x, v1.position.y, v1.position.x);
			glVertex3f(v2.position.x, v2.position.y, v2.position.x);
			glVertex3f(v2.position.x, v2.position.y, v2.position.x);
			glVertex3f(v3.position.x, v3.position.y, v3.position.x);
			glVertex3f(v3.position.x, v3.position.y, v3.position.x);
			glVertex3f(v1.position.x, v1.position.y, v1.position.x);
		}
	glEnd();
}

void Mesh::renderTriangles(const VertexList& vertices, const TriangleList& triangles)
{
	glBegin(GL_TRIANGLES);
	if (triangleColouring == MESH_ALTERNATING_TRIANGLES)
	{
		// Whole for-loop put it if-statement so there isn't a branch every iteration (costly operation
		for (unsigned int i = 0; (i < triangles.size()); i++)
		{
			const Vector3& col = ALTERNATING_TRIANGLE_COLOURS[i % NUM_ALTERNATING_COLOURS];
			glColor3f(col.x, col.y, col.y);
			renderTriangle(vertices, tris[i]);
		}
	}
	else
	{
		for (TriangleList::const_iterator it = triangles.begin(); (it != triangles.end()); it++)
			renderTriangle(vertices, *it);
	}
	glEnd();
}

void Mesh::renderNormals(const VertexList& vertices)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_LINES);
		for (VertexList::const_iterator it = vertices.begin(); (it != vertices.end()); it++)
		{
			const Vector3& position = it->position;
			const Vector3& normal = it->normal;
			Vector3 end = position + (normal * NORMAL_SCALING_FACTOR);
			glVertex3f(it->position.x, it->position.y, it->position.z);
			glVertex3f(end.x, end.y, end.y);
		}
	glEnd();
}

/* Draw a torus */
#include <math.h>
static void torus(int numc, int numt)
{
   int i, j, k;
   double s, t, x, y, z, twopi;

   twopi = 2 * (double)M_PI;
   for (i = 0; i < numc; i++) {
      glBegin(GL_QUAD_STRIP);
      for (j = 0; j <= numt; j++) {
         for (k = 1; k >= 0; k--) {
            s = (i + k) % numc + 0.5;
            t = j % numt;

            x = (1+.1*cos(s*twopi/numc))*cos(t*twopi/numt);
            y = (1+.1*cos(s*twopi/numc))*sin(t*twopi/numt);
            z = .1 * sin(s * twopi / numc);

                        const Vector3& col = ALTERNATING_TRIANGLE_COLOURS[(i * j) % NUM_ALTERNATING_COLOURS];
                       glColor3f(col.x, col.y, col.y);

            glVertex3f(x, y, z);
         }
      }
      glEnd();
   }
}

void Mesh::render()
{
	/*MatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glRotatef(rot.x, 1.0f, 0.0f, 0.0f);
	glRotatef(rot.y, 0.0f, 1.0f, 0.0f);
	glRotatef(rot.z, 0.0f, 0.0f, 1.0f);
	torus(8, 8);
	glPopMatrix();
	return;*/

	// If texturing has been enabled, ensure we set the correct OpenGL state
	if (triangleColouring == MESH_TEXTURE)
	{
		// If texture hasn't been loaded yet - load it now!
		// This is lazy initialisation
		if (!surfaceTexture)
			surfaceTexture = new Texture("resources/world_texture.jpg");
		glEnable(GL_TEXTURE_2D);
		surfaceTexture->bind();
	}

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	// Perform local model transformations on mesh
	Matrix44 transformation =  Matrix44::translation(pos.x, pos.y, pos.z);
	transformation = transformation * Matrix44::xyzRotation(rot);
	// Transform vertices using position and orientation of drawable
	VertexList transformedVerts = verts;
	// If using per-face normals and not per-vertex normals, compute surface normals now
	if (useSurfaceNormals)
	{
		Vector3List surfaceNormals = computeSurfaceNormals(transformedVerts, tris);
		for (int i = 0; (i < surfaceNormals.size()); i++)
		{
			transformedVerts[i].normal = surfaceNormals[i];
		}
	}
	for (VertexList::iterator it = transformedVerts.begin(); (it != transformedVerts.end()); it++)
	{
		it->position = transformation * it->position;
		it->normal = (transformation * it->normal).normalise();
	}

	// How mesh is drawn depends on geometry type chosen
	switch (geomType)
	{
	case MESH_GEOM_POINTS:
		renderPoints(transformedVerts);
		break;
	case MESH_GEOM_LINES:
		renderLines(transformedVerts, tris);
		break;
	case MESH_GEOM_TRIANGLES:
		renderTriangles(transformedVerts, tris);
		break;
	}
	// Also draw lines reprensenting vertex normals
	if (drawNormals)
	{
		renderNormals(transformedVerts);
	}

	glPopMatrix();

	// Make sure the mesh's texture is unbinded after rendering
	if (triangleColouring == MESH_TEXTURE)
	{
		if (surfaceTexture)
			surfaceTexture->unbind();
		glDisable(GL_TEXTURE_2D);
	}
}

Vector3List Mesh::computeSurfaceNormals(const VertexList& vertices, const TriangleList& triangles)
{
	Vector3List normals;
	normals.resize(vertices.size());

	for (TriangleList::const_iterator it = triangles.begin();
		(it != triangles.end()); it++)
	{
		// Get two points of the triangle and create two vectors from them (sides of triangle)
		Vector3 s1 = vertices[it->v2].position - vertices[it->v1].position;
		Vector3 s2 = vertices[it->v3].position - vertices[it->v1].position;
		// Compute cross product of sides to get surface normal
		Vector3 surfaceNormal = s1.cross(s2).normalise();
		// Assign this surface normal to all v
		normals[it->v1] = surfaceNormal;
		normals[it->v2] = surfaceNormal;
		normals[it->v3] = surfaceNormal;
	}

	return normals;
}
<|endoftext|>


<commit_before>#include "Arduino.h"
#include "Ndef.h"

//void Adafruit_NFCShield_I2C::PrintHex(const byte * data, const uint32_t numBytes)
void PrintHex(const byte * data, const uint32_t numBytes)
{
  uint32_t szPos;
  for (szPos=0; szPos < numBytes; szPos++)
  {
    Serial.print("0x");
    // Append leading 0 for small values
    if (data[szPos] <= 0xF)
      Serial.print("0");
    Serial.print(data[szPos]&0xff, HEX);
    if ((numBytes > 1) && (szPos != numBytes - 1))
    {
      Serial.print(" ");
    }
  }
  Serial.println("");
}

NdefRecord::NdefRecord()
{
    _tnf = 0;
    _typeLength = 0;
    _payloadLength = 0;
    _idLength = 0;
}

NdefRecord::NdefRecord(const NdefRecord& rhs)
{
    _tnf = rhs._tnf;
    _typeLength = rhs._typeLength;
    _payloadLength = rhs._payloadLength;
    _idLength = rhs._idLength;

    _type = (uint8_t*)malloc(_typeLength);
    memcpy(_type, rhs._type, _typeLength);

    _payload = (uint8_t*)malloc(_payloadLength);
    memcpy(_payload, rhs._payload, _payloadLength);

    _id = (uint8_t*)malloc(_idLength);
    memcpy(_id, rhs._id, _idLength);
}

// TODO NdefRecord::NdefRecord(tnf, type, payload, id)

NdefRecord::~NdefRecord()
{
    if (_typeLength)
    {
        free(_type);
    }

    if (_payloadLength)
    {
        free(_payload);
    }

    if (_idLength)
    {
        free(_id);
    }
}

NdefRecord& NdefRecord::operator=(const NdefRecord& rhs)
{
    if (this != &rhs)
    {
        _tnf = rhs._tnf;
        _typeLength = rhs._typeLength;
        _payloadLength = rhs._payloadLength;
        _idLength = rhs._idLength;

        // TODO need to free _type, _payload, and _id if they exist

        _type = (uint8_t*)malloc(_typeLength);
        memcpy(_type, rhs._type, _typeLength);

        _payload = (uint8_t*)malloc(_payloadLength);
        memcpy(_payload, rhs._payload, _payloadLength);

        _id = (uint8_t*)malloc(_idLength);
        memcpy(_id, rhs._id, _idLength);
    }
    return *this;
}

// size of records in bytes
int NdefRecord::getEncodedSize()
{
    int size = 2; // tnf + typeLength
    if (_payloadLength > 0xFF)
    {
        size += 4;
    }
    else
    {
        size += 1;
    }

    if (_idLength)
    {
        size += 1;
    }

    size += (_typeLength + _payloadLength + _idLength);

    return size;
}

void NdefRecord::encode(uint8_t* data, bool firstRecord, bool lastRecord)
{
    // assert data > getEncodedSize()

    uint8_t* data_ptr = &data[0];

    *data_ptr = getTnfByte(firstRecord, lastRecord);
    data_ptr += 1;

    *data_ptr = _typeLength;
    data_ptr += 1;

    *data_ptr = _payloadLength; // TODO handle sr == false
    data_ptr += 1;
    if (_idLength)
    {
        *data_ptr = _idLength;
        data_ptr += 1;
    }

    //Serial.println(2);
    memcpy(data_ptr, _type, _typeLength);
    data_ptr += _typeLength;

    memcpy(data_ptr, _payload, _payloadLength);
    data_ptr += _payloadLength;

    if (_idLength)
    {
        memcpy(data_ptr, _id, _idLength);
        data_ptr += _idLength;
    }
}

uint8_t NdefRecord::getTnfByte(bool firstRecord, bool lastRecord)
{
    int value = _tnf;

    if (firstRecord) { // mb
        value = value | 0x80;
    }

    if (lastRecord) { //
        value = value | 0x40;
    }

    // chunked flag is always false for now
    // if (cf) {
    //     value = value | 0x20;
    // }

    if (_typeLength <= 0xFF) { // TODO test 0xFF on tag
        value = value | 0x10;
    }

    if (_idLength) {
        value = value | 0x8;
    }

    return value;
}

uint8_t NdefRecord::getTnf()
{
    return _tnf;
}

void NdefRecord::setTnf(uint8_t tnf)
{
    _tnf = tnf;
}

uint8_t NdefRecord::getTypeLength()
{
    return _typeLength;
}

int NdefRecord::getPayloadLength()
{
    return _payloadLength;
}

uint8_t NdefRecord::getIdLength()
{
    return _idLength;
}

// TODO don't return an array we created
// NdefRecord::getType(uint8_t * type) and copy into their array
// OR return an object that has the type and the array
uint8_t * NdefRecord::getType()
{
    return _type;
}

void NdefRecord::setType(uint8_t * type, const int numBytes)
{
    _type = (uint8_t*)malloc(numBytes);
    memcpy(_type, type, numBytes);
    _typeLength = numBytes;
}

uint8_t * NdefRecord::getPayload()
{
    return _payload;
}

void NdefRecord::setPayload(uint8_t * payload, const int numBytes)
{
    _payload = (uint8_t*)malloc(numBytes);
    memcpy(_payload, payload, numBytes);
    _payloadLength = numBytes;
}

uint8_t * NdefRecord::getId()
{
    return _id;
}

void NdefRecord::setId(uint8_t * id, const int numBytes)
{

    _id = (uint8_t*)malloc(numBytes);
    memcpy(_id, id, numBytes);
    _idLength = numBytes;
}

void NdefRecord::print()
{
    Serial.println("  NDEF Record");
    Serial.print("    TNF 0x");Serial.println(_tnf, HEX);
    Serial.print("    Type Length 0x");Serial.println(_typeLength, HEX);
    Serial.print("    Payload Length 0x");Serial.println(_payloadLength, HEX);
    if (_idLength)
    {
        Serial.print("    Id Length 0x");Serial.println(_idLength, HEX);
    }
    Serial.print("    Type ");PrintHex(_type, _typeLength);
    Serial.print("    Payload ");PrintHex(_payload, _payloadLength);
    if (_idLength)
    {
        Serial.print("    Id ");PrintHex(_id, _idLength);
    }
    Serial.print("    Record is ");Serial.print(getEncodedSize());Serial.println(" bytes");

}

NdefMessage::NdefMessage(void)
{
    _recordCount = 0;
}

NdefMessage::NdefMessage(byte * data, const int numBytes)
{
    Serial.print("Decoding ");Serial.print(numBytes);Serial.println(" bytes");
    PrintHex(data, numBytes);
    // _records = (NdefRecord*)malloc(sizeof(NdefRecord *) * MAX_NDEF_RECORDS);
    _recordCount = 0;

    int index = 0;

    while (index <= numBytes) {

        // decode tnf - first byte is tnf with bit flags
        // see the NFDEF spec for more info
        byte tnf_byte = data[index];
        bool mb = (tnf_byte & 0x80) != 0;
        bool me = (tnf_byte & 0x40) != 0;
        bool cf = (tnf_byte & 0x20) != 0;
        bool sr = (tnf_byte & 0x10) != 0;
        bool il = (tnf_byte & 0x8) != 0;
        byte tnf = (tnf_byte & 0x7);

        NdefRecord record = NdefRecord();
        record.setTnf(tnf);

        index++;
        int typeLength = data[index];

        int payloadLength = 0;
        if (sr)
        {
            index++;
            payloadLength = data[index];
        }
        else
        {
            payloadLength = ((0xFF & data[++index]) << 24) | ((0xFF & data[++index]) << 26) |
            ((0xFF & data[++index]) << 8) | (0xFF & data[++index]);
        }

        int idLength = 0;
        if (il)
        {
            index++;
            idLength = data[index];
        }

        index++;
        record.setType(&data[index], typeLength);
        index += typeLength;

        if (il)
        {
            record.setId(&data[index], idLength);
            index += idLength;
        }

        record.setPayload(&data[index], payloadLength);
        index += payloadLength;

        add(record);

        if (me) break; // last message
    }

}

NdefMessage::~NdefMessage()
{
    //free(_records);
}

int NdefMessage::recordCount()
{
    return _recordCount;
}

int NdefMessage::getEncodedSize()
{
    int size = 0;
    int i;
    for (i = 0; i < _recordCount; i++)
    {
        size += _records[i].getEncodedSize();
    }
    return size;
}

void NdefMessage::encode(uint8_t* data)
{
    // assert sizeof(data) >= getEncodedSize()
    uint8_t* data_ptr = &data[0];

    int i;
    for (i = 0; i < _recordCount; i++)
    {
        _records[i].encode(data_ptr, i == 0, (i + 1) == _recordCount);
        // TODO can NdefRecord.encode return the record size?
        data_ptr += _records[i].getEncodedSize();
    }

    // TODO don't print here
    Serial.println("\nEncoded");
    PrintHex(data, getEncodedSize());
}

void NdefMessage::add(NdefRecord record)
{

    if (_recordCount < MAX_NDEF_RECORDS)
    {
        _records[_recordCount] = record;
        _recordCount++;
    }
    else
    {
        // TODO consider returning status
        Serial.println("WARNING: Too many records. Increase MAX_NDEF_RECORDS.");
    }
}

// TODO would NdefRecord::mimeMediaRecord be better?
void NdefMessage::addMimeMediaRecord(String mimeType, String payload)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_MIME_MEDIA);

    byte type[mimeType.length() + 1];
    mimeType.getBytes(type, sizeof(type));
    r->setType(type, mimeType.length());

    byte payloadBytes[payload.length() + 1];
    payload.getBytes(payloadBytes, sizeof(payloadBytes));
    r->setPayload(payloadBytes, payload.length());

    add(*r);

    /*
    TODO call other method
    byte payloadBytes[payload.length() + 1];
    payload.getBytes(payloadBytes, sizeof(payloadBytes));

    addMimeMediaRecord(mimeType, payloadBytes, payload.length);
    */
}

void NdefMessage::addMimeMediaRecord(String mimeType, uint8_t* payload, int payloadLength)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_MIME_MEDIA);

    byte type[mimeType.length() + 1];
    mimeType.getBytes(type, sizeof(type));
    r->setType(type, mimeType.length());

    r->setPayload(payload, payloadLength);

    add(*r);
}

void NdefMessage::addTextRecord(String text)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_WELL_KNOWN);

    uint8_t RTD_TEXT[1] = { 0x54 }; // TODO this should be a constant or preprocessor
    r->setType(RTD_TEXT, sizeof(RTD_TEXT));

    // TODO language encoding
    byte payload[text.length() + 1];
    text.getBytes(payload, sizeof(payload));
    r->setPayload(payload, text.length());

    add(*r);
}

void NdefMessage::addTextRecord(String text, String encoding)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_WELL_KNOWN);

    uint8_t RTD_TEXT[1] = { 0x54 }; // TODO this should be a constant or preprocessor
    r->setType(RTD_TEXT, sizeof(RTD_TEXT));

    // X is a placeholder for encoding length
    String payloadString = "X" + encoding + text;

    byte payload[payloadString.length() + 1];
    payloadString.getBytes(payload, sizeof(payload));

    // replace X with the real length
    payload[0] = encoding.length();

    r->setPayload(payload, payloadString.length());

    add(*r);
}

void NdefMessage::addUriRecord(String uri)
{

}

void NdefMessage::addEmptyRecord()
{

}

NdefRecord NdefMessage::get(int index)
{
    if (index > -1 && index < _recordCount)
    {
        return _records[_recordCount];
    }
}

void NdefMessage::print()
{
    Serial.print("\nNDEF Message ");Serial.print(_recordCount);Serial.print(" record");
    _recordCount == 1 ? Serial.print(", ") : Serial.print("s, ");
    Serial.print(getEncodedSize());Serial.println(" bytes");

    int i;
    for (i = 0; i < _recordCount; i++)
    {
         _records[i].print();
    }
}
<commit_msg>combine implementation of addTextRecord<commit_after>#include "Arduino.h"
#include "Ndef.h"

//void Adafruit_NFCShield_I2C::PrintHex(const byte * data, const uint32_t numBytes)
void PrintHex(const byte * data, const uint32_t numBytes)
{
  uint32_t szPos;
  for (szPos=0; szPos < numBytes; szPos++)
  {
    Serial.print("0x");
    // Append leading 0 for small values
    if (data[szPos] <= 0xF)
      Serial.print("0");
    Serial.print(data[szPos]&0xff, HEX);
    if ((numBytes > 1) && (szPos != numBytes - 1))
    {
      Serial.print(" ");
    }
  }
  Serial.println("");
}

NdefRecord::NdefRecord()
{
    _tnf = 0;
    _typeLength = 0;
    _payloadLength = 0;
    _idLength = 0;
}

NdefRecord::NdefRecord(const NdefRecord& rhs)
{
    _tnf = rhs._tnf;
    _typeLength = rhs._typeLength;
    _payloadLength = rhs._payloadLength;
    _idLength = rhs._idLength;

    _type = (uint8_t*)malloc(_typeLength);
    memcpy(_type, rhs._type, _typeLength);

    _payload = (uint8_t*)malloc(_payloadLength);
    memcpy(_payload, rhs._payload, _payloadLength);

    _id = (uint8_t*)malloc(_idLength);
    memcpy(_id, rhs._id, _idLength);
}

// TODO NdefRecord::NdefRecord(tnf, type, payload, id)

NdefRecord::~NdefRecord()
{
    if (_typeLength)
    {
        free(_type);
    }

    if (_payloadLength)
    {
        free(_payload);
    }

    if (_idLength)
    {
        free(_id);
    }
}

NdefRecord& NdefRecord::operator=(const NdefRecord& rhs)
{
    if (this != &rhs)
    {
        _tnf = rhs._tnf;
        _typeLength = rhs._typeLength;
        _payloadLength = rhs._payloadLength;
        _idLength = rhs._idLength;

        // TODO need to free _type, _payload, and _id if they exist

        _type = (uint8_t*)malloc(_typeLength);
        memcpy(_type, rhs._type, _typeLength);

        _payload = (uint8_t*)malloc(_payloadLength);
        memcpy(_payload, rhs._payload, _payloadLength);

        _id = (uint8_t*)malloc(_idLength);
        memcpy(_id, rhs._id, _idLength);
    }
    return *this;
}

// size of records in bytes
int NdefRecord::getEncodedSize()
{
    int size = 2; // tnf + typeLength
    if (_payloadLength > 0xFF)
    {
        size += 4;
    }
    else
    {
        size += 1;
    }

    if (_idLength)
    {
        size += 1;
    }

    size += (_typeLength + _payloadLength + _idLength);

    return size;
}

void NdefRecord::encode(uint8_t* data, bool firstRecord, bool lastRecord)
{
    // assert data > getEncodedSize()

    uint8_t* data_ptr = &data[0];

    *data_ptr = getTnfByte(firstRecord, lastRecord);
    data_ptr += 1;

    *data_ptr = _typeLength;
    data_ptr += 1;

    *data_ptr = _payloadLength; // TODO handle sr == false
    data_ptr += 1;
    if (_idLength)
    {
        *data_ptr = _idLength;
        data_ptr += 1;
    }

    //Serial.println(2);
    memcpy(data_ptr, _type, _typeLength);
    data_ptr += _typeLength;

    memcpy(data_ptr, _payload, _payloadLength);
    data_ptr += _payloadLength;

    if (_idLength)
    {
        memcpy(data_ptr, _id, _idLength);
        data_ptr += _idLength;
    }
}

uint8_t NdefRecord::getTnfByte(bool firstRecord, bool lastRecord)
{
    int value = _tnf;

    if (firstRecord) { // mb
        value = value | 0x80;
    }

    if (lastRecord) { //
        value = value | 0x40;
    }

    // chunked flag is always false for now
    // if (cf) {
    //     value = value | 0x20;
    // }

    if (_typeLength <= 0xFF) { // TODO test 0xFF on tag
        value = value | 0x10;
    }

    if (_idLength) {
        value = value | 0x8;
    }

    return value;
}

uint8_t NdefRecord::getTnf()
{
    return _tnf;
}

void NdefRecord::setTnf(uint8_t tnf)
{
    _tnf = tnf;
}

uint8_t NdefRecord::getTypeLength()
{
    return _typeLength;
}

int NdefRecord::getPayloadLength()
{
    return _payloadLength;
}

uint8_t NdefRecord::getIdLength()
{
    return _idLength;
}

// TODO don't return an array we created
// NdefRecord::getType(uint8_t * type) and copy into their array
// OR return an object that has the type and the array
uint8_t * NdefRecord::getType()
{
    return _type;
}

void NdefRecord::setType(uint8_t * type, const int numBytes)
{
    _type = (uint8_t*)malloc(numBytes);
    memcpy(_type, type, numBytes);
    _typeLength = numBytes;
}

uint8_t * NdefRecord::getPayload()
{
    return _payload;
}

void NdefRecord::setPayload(uint8_t * payload, const int numBytes)
{
    _payload = (uint8_t*)malloc(numBytes);
    memcpy(_payload, payload, numBytes);
    _payloadLength = numBytes;
}

uint8_t * NdefRecord::getId()
{
    return _id;
}

void NdefRecord::setId(uint8_t * id, const int numBytes)
{

    _id = (uint8_t*)malloc(numBytes);
    memcpy(_id, id, numBytes);
    _idLength = numBytes;
}

void NdefRecord::print()
{
    Serial.println("  NDEF Record");
    Serial.print("    TNF 0x");Serial.println(_tnf, HEX);
    Serial.print("    Type Length 0x");Serial.println(_typeLength, HEX);
    Serial.print("    Payload Length 0x");Serial.println(_payloadLength, HEX);
    if (_idLength)
    {
        Serial.print("    Id Length 0x");Serial.println(_idLength, HEX);
    }
    Serial.print("    Type ");PrintHex(_type, _typeLength);
    Serial.print("    Payload ");PrintHex(_payload, _payloadLength);
    if (_idLength)
    {
        Serial.print("    Id ");PrintHex(_id, _idLength);
    }
    Serial.print("    Record is ");Serial.print(getEncodedSize());Serial.println(" bytes");

}

NdefMessage::NdefMessage(void)
{
    _recordCount = 0;
}

NdefMessage::NdefMessage(byte * data, const int numBytes)
{
    Serial.print("Decoding ");Serial.print(numBytes);Serial.println(" bytes");
    PrintHex(data, numBytes);
    // _records = (NdefRecord*)malloc(sizeof(NdefRecord *) * MAX_NDEF_RECORDS);
    _recordCount = 0;

    int index = 0;

    while (index <= numBytes) {

        // decode tnf - first byte is tnf with bit flags
        // see the NFDEF spec for more info
        byte tnf_byte = data[index];
        bool mb = (tnf_byte & 0x80) != 0;
        bool me = (tnf_byte & 0x40) != 0;
        bool cf = (tnf_byte & 0x20) != 0;
        bool sr = (tnf_byte & 0x10) != 0;
        bool il = (tnf_byte & 0x8) != 0;
        byte tnf = (tnf_byte & 0x7);

        NdefRecord record = NdefRecord();
        record.setTnf(tnf);

        index++;
        int typeLength = data[index];

        int payloadLength = 0;
        if (sr)
        {
            index++;
            payloadLength = data[index];
        }
        else
        {
            payloadLength = ((0xFF & data[++index]) << 24) | ((0xFF & data[++index]) << 26) |
            ((0xFF & data[++index]) << 8) | (0xFF & data[++index]);
        }

        int idLength = 0;
        if (il)
        {
            index++;
            idLength = data[index];
        }

        index++;
        record.setType(&data[index], typeLength);
        index += typeLength;

        if (il)
        {
            record.setId(&data[index], idLength);
            index += idLength;
        }

        record.setPayload(&data[index], payloadLength);
        index += payloadLength;

        add(record);

        if (me) break; // last message
    }

}

NdefMessage::~NdefMessage()
{
    //free(_records);
}

int NdefMessage::recordCount()
{
    return _recordCount;
}

int NdefMessage::getEncodedSize()
{
    int size = 0;
    int i;
    for (i = 0; i < _recordCount; i++)
    {
        size += _records[i].getEncodedSize();
    }
    return size;
}

void NdefMessage::encode(uint8_t* data)
{
    // assert sizeof(data) >= getEncodedSize()
    uint8_t* data_ptr = &data[0];

    int i;
    for (i = 0; i < _recordCount; i++)
    {
        _records[i].encode(data_ptr, i == 0, (i + 1) == _recordCount);
        // TODO can NdefRecord.encode return the record size?
        data_ptr += _records[i].getEncodedSize();
    }

    // TODO don't print here
    Serial.println("\nEncoded");
    PrintHex(data, getEncodedSize());
}

void NdefMessage::add(NdefRecord record)
{

    if (_recordCount < MAX_NDEF_RECORDS)
    {
        _records[_recordCount] = record;
        _recordCount++;
    }
    else
    {
        // TODO consider returning status
        Serial.println("WARNING: Too many records. Increase MAX_NDEF_RECORDS.");
    }
}

// TODO would NdefRecord::mimeMediaRecord be better?
void NdefMessage::addMimeMediaRecord(String mimeType, String payload)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_MIME_MEDIA);

    byte type[mimeType.length() + 1];
    mimeType.getBytes(type, sizeof(type));
    r->setType(type, mimeType.length());

    byte payloadBytes[payload.length() + 1];
    payload.getBytes(payloadBytes, sizeof(payloadBytes));
    r->setPayload(payloadBytes, payload.length());

    add(*r);

    /*
    TODO call other method
    byte payloadBytes[payload.length() + 1];
    payload.getBytes(payloadBytes, sizeof(payloadBytes));

    addMimeMediaRecord(mimeType, payloadBytes, payload.length);
    */
}

void NdefMessage::addMimeMediaRecord(String mimeType, uint8_t* payload, int payloadLength)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_MIME_MEDIA);

    byte type[mimeType.length() + 1];
    mimeType.getBytes(type, sizeof(type));
    r->setType(type, mimeType.length());

    r->setPayload(payload, payloadLength);

    add(*r);
}

void NdefMessage::addTextRecord(String text)
{
    addTextRecord(text, "en");
}

void NdefMessage::addTextRecord(String text, String encoding)
{
    NdefRecord* r = new NdefRecord();
    r->setTnf(TNF_WELL_KNOWN);

    uint8_t RTD_TEXT[1] = { 0x54 }; // TODO this should be a constant or preprocessor
    r->setType(RTD_TEXT, sizeof(RTD_TEXT));

    // X is a placeholder for encoding length
    String payloadString = "X" + encoding + text;

    byte payload[payloadString.length() + 1];
    payloadString.getBytes(payload, sizeof(payload));

    // replace X with the real length
    payload[0] = encoding.length();

    r->setPayload(payload, payloadString.length());

    add(*r);
}

void NdefMessage::addUriRecord(String uri)
{

}

void NdefMessage::addEmptyRecord()
{

}

NdefRecord NdefMessage::get(int index)
{
    if (index > -1 && index < _recordCount)
    {
        return _records[_recordCount];
    }
}

void NdefMessage::print()
{
    Serial.print("\nNDEF Message ");Serial.print(_recordCount);Serial.print(" record");
    _recordCount == 1 ? Serial.print(", ") : Serial.print("s, ");
    Serial.print(getEncodedSize());Serial.println(" bytes");

    int i;
    for (i = 0; i < _recordCount; i++)
    {
         _records[i].print();
    }
}
<|endoftext|>


<commit_before>#include <string.h>
#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <memory.h>
#include <ctime>
#include <assert.h>
#define pi 3.14159
#define mod 1000000007
using namespace std;
long long int a[500000];
int main()
{
	long long int t,flag=0,value=0;
	cin>>t;
	while(t--)
	{
		int a,b;
		cin>>a>>b;
		flag = flag + b -a;
		if(value < flag)
		{
			value = flag;
		}
	}
	cout<<value;
	return 0;
}
<commit_msg>Delete Tram.cpp<commit_after><|endoftext|>


<commit_before>#include <nan.h>
#include "addon.h"
#include "dvbtee-parser.h"

void libVersion(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  v8::Local<v8::Array> version = Nan::New<v8::Array>();

  version->Set(0, Nan::New<v8::Number>(LIBDVBTEE_VERSION_A) );
  version->Set(1, Nan::New<v8::Number>(LIBDVBTEE_VERSION_B) );
  version->Set(2, Nan::New<v8::Number>(LIBDVBTEE_VERSION_C) );

  info.GetReturnValue().Set(version);
}

void logLevel(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  libdvbtee_set_debug_level((info[0]->IsNumber()) ? info[0]->Uint32Value() : 255,
                            (info[1]->IsNumber()) ? info[1]->Uint32Value() : 0);

  info.GetReturnValue().Set(info.Holder());
}

NAN_MODULE_INIT(InitAll) {

  Nan::Set(target, Nan::New<v8::String>("logLevel").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(logLevel)).ToLocalChecked());

  Nan::Set(target, Nan::New<v8::String>("libVersion").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libVersion)).ToLocalChecked());

  dvbteeParser::Init(target);
}

NODE_MODULE(dvbtee, InitAll)
<commit_msg>addon: add functions getTableDecoderIds & getDescriptorDecoderIds<commit_after>#include <nan.h>
#include "addon.h"
#include "dvbtee-parser.h"

void libVersion(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  v8::Local<v8::Array> version = Nan::New<v8::Array>();

  version->Set(0, Nan::New<v8::Number>(LIBDVBTEE_VERSION_A) );
  version->Set(1, Nan::New<v8::Number>(LIBDVBTEE_VERSION_B) );
  version->Set(2, Nan::New<v8::Number>(LIBDVBTEE_VERSION_C) );

  info.GetReturnValue().Set(version);
}

void logLevel(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  libdvbtee_set_debug_level((info[0]->IsNumber()) ? info[0]->Uint32Value() : 255,
                            (info[1]->IsNumber()) ? info[1]->Uint32Value() : 0);

  info.GetReturnValue().Set(info.Holder());
}

template<typename T> v8::Local<v8::Array> vectorToV8Array(std::vector<T> v) {

  v8::Local<v8::Array> a = Nan::New<v8::Array>();
  unsigned int pos = 0;

  for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it)
    a->Set(pos++, Nan::New(*it) );

  return a;
}

void getTableDecoderIds(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  info.GetReturnValue().Set(vectorToV8Array(dvbtee::decode::TableRegistry::instance().list()));
}

void getDescriptorDecoderIds(const Nan::FunctionCallbackInfo<v8::Value>& info) {

  info.GetReturnValue().Set(vectorToV8Array(dvbtee::decode::DescriptorRegistry::instance().list()));
}

NAN_MODULE_INIT(InitAll) {

  Nan::Set(target, Nan::New<v8::String>("logLevel").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(logLevel)).ToLocalChecked());

  Nan::Set(target, Nan::New<v8::String>("libVersion").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libVersion)).ToLocalChecked());

  Nan::Set(target, Nan::New<v8::String>("getTableDecoderIds").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(getTableDecoderIds)).ToLocalChecked());

  Nan::Set(target, Nan::New<v8::String>("getDescriptorDecoderIds").ToLocalChecked(),
    Nan::GetFunction(Nan::New<v8::FunctionTemplate>(getDescriptorDecoderIds)).ToLocalChecked());

  dvbteeParser::Init(target);
}

NODE_MODULE(dvbtee, InitAll)
<|endoftext|>