<commit_before>#include "StdH.h"
#include "Colors.h"

MRAGPP_NAMESPACE_BEGIN;

#define MAX3(x, y, z) (x > y ? (x > z ? x : z) : (y > z ? y : z))
#define MIN3(x, y, z) (x < y ? (x < z ? x : z) : (y < z ? y : z))

inline rgb col2rgb(COLOR col)
{
  rgb rgb;
  rgb.r = MRAG_COLOR_EXPLODE_R(col);
  rgb.g = MRAG_COLOR_EXPLODE_G(col);
  rgb.b = MRAG_COLOR_EXPLODE_B(col);
  return rgb;
}

inline hsv col2hsv(COLOR col)
{
  return rgb2hsv(col2rgb(col));
}

inline COLOR rgb2col(const rgb &rgb)
{
  return MRAG_COLOR_RGB(rgb.r, rgb.g, rgb.b);
}

inline COLOR hsv2col(const hsv &hsv)
{
  return rgb2col(hsv2rgb(hsv));
}

inline hsv rgb2hsv(const rgb &rgb)
{
  float h, s = 0;
  float r = rgb.r / 255.0f;
  float g = rgb.g / 255.0f;
  float b = rgb.b / 255.0f;
  float M = MAX3(r, g, b);
  float c = M - MIN3(r, g, b);
  if     (c == 0) h = 0;
  else if(M == r) h = fmod(((g - b) / c), 6) * 60;
  else if(M == g) h = ((b - r) / c + 2) * 60;
  else h = ((r - g) / c + 4) * 60;
  if(h < 0.0f) h += 360;
  if(c != 0) s = c / M;
  hsv hsv;
  hsv.h = (short)h;
  hsv.s = (unsigned char)(s * 100.0f);
  hsv.v = (unsigned char)(M * 100.0f);
  return hsv;
}

inline rgb hsv2rgb(const hsv &hsv)
{
  float h = mthClamp((float)hsv.h, 0.0f, 359.0f);
  float s = mthClamp(hsv.s / 100.0f, 0.0f, 1.0f);
  float v = mthClamp(hsv.v / 100.0f, 0.0f, 1.0f);
  float c = v * s;
  float x = c * (1 - abs(fmod(h / 60.0f, 2) - 1));
  float r = 0, g = 0, b = 0;
  if     (h >=   0 && h <  60) { r = c; g = x; }
  else if(h >=  60 && h < 120) { r = x; g = c; }
  else if(h >= 120 && h < 180) { g = c; b = x; }
  else if(h >= 180 && h < 240) { g = x; b = c; }
  else if(h >= 240 && h < 300) { r = x; b = c; }
  else if(h >= 300 && h < 360) { r = c; b = x; }
  rgb rgb;
  rgb.r = (unsigned char)((r + (v - c)) * 255);
  rgb.g = (unsigned char)((g + (v - c)) * 255);
  rgb.b = (unsigned char)((b + (v - c)) * 255);
  return rgb;
}

inline COLOR colMod(COLOR col, float fModH, float fModS, float fModV)
{
  hsv hsv = col2hsv(col);
  hsv.h = (int)(hsv.h * fModH);
  hsv.s = (int)(hsv.s * fModS);
  hsv.v = (int)(hsv.v * fModV);
  return hsv2col(hsv);
}

MRAGPP_NAMESPACE_END;
<commit_msg>Fixed warning in Colors.cpp<commit_after>#include "StdH.h"
#include "Colors.h"

MRAGPP_NAMESPACE_BEGIN;

#define MAX3(x, y, z) (x > y ? (x > z ? x : z) : (y > z ? y : z))
#define MIN3(x, y, z) (x < y ? (x < z ? x : z) : (y < z ? y : z))

inline rgb col2rgb(COLOR col)
{
  rgb rgb;
  rgb.r = MRAG_COLOR_EXPLODE_R(col);
  rgb.g = MRAG_COLOR_EXPLODE_G(col);
  rgb.b = MRAG_COLOR_EXPLODE_B(col);
  return rgb;
}

inline hsv col2hsv(COLOR col)
{
  return rgb2hsv(col2rgb(col));
}

inline COLOR rgb2col(const rgb &rgb)
{
  return MRAG_COLOR_RGB(rgb.r, rgb.g, rgb.b);
}

inline COLOR hsv2col(const hsv &hsv)
{
  return rgb2col(hsv2rgb(hsv));
}

inline hsv rgb2hsv(const rgb &rgb)
{
  float h, s = 0;
  float r = rgb.r / 255.0f;
  float g = rgb.g / 255.0f;
  float b = rgb.b / 255.0f;
  float M = MAX3(r, g, b);
  float c = M - MIN3(r, g, b);
  if     (c == 0) h = 0;
  else if(M == r) h = fmod(((g - b) / c), 6) * 60;
  else if(M == g) h = ((b - r) / c + 2) * 60;
  else h = ((r - g) / c + 4) * 60;
  if(h < 0.0f) h += 360;
  if(c != 0) s = c / M;
  hsv hsv;
  hsv.h = (short)h;
  hsv.s = (unsigned char)(s * 100.0f);
  hsv.v = (unsigned char)(M * 100.0f);
  return hsv;
}

inline rgb hsv2rgb(const hsv &hsv)
{
  float h = mthClamp((float)hsv.h, 0.0f, 359.0f);
  float s = mthClamp(hsv.s / 100.0f, 0.0f, 1.0f);
  float v = mthClamp(hsv.v / 100.0f, 0.0f, 1.0f);
  float c = v * s;
  float x = c * (1 - fabs(fmod(h / 60.0f, 2) - 1));
  float r = 0, g = 0, b = 0;
  if     (h >=   0 && h <  60) { r = c; g = x; }
  else if(h >=  60 && h < 120) { r = x; g = c; }
  else if(h >= 120 && h < 180) { g = c; b = x; }
  else if(h >= 180 && h < 240) { g = x; b = c; }
  else if(h >= 240 && h < 300) { r = x; b = c; }
  else if(h >= 300 && h < 360) { r = c; b = x; }
  rgb rgb;
  rgb.r = (unsigned char)((r + (v - c)) * 255);
  rgb.g = (unsigned char)((g + (v - c)) * 255);
  rgb.b = (unsigned char)((b + (v - c)) * 255);
  return rgb;
}

inline COLOR colMod(COLOR col, float fModH, float fModS, float fModV)
{
  hsv hsv = col2hsv(col);
  hsv.h = (int)(hsv.h * fModH);
  hsv.s = (int)(hsv.s * fModS);
  hsv.v = (int)(hsv.v * fModV);
  return hsv2col(hsv);
}

MRAGPP_NAMESPACE_END;
<|endoftext|>


<commit_before>
#include "Config.hpp"

/* CONFIG GROUP */
ConfigGroup::~ConfigGroup(){
  clear();
}

void ConfigGroup::clear(){
  std::map<std::string, ConfigGroup*>::iterator it = els.begin();
  while(it != els.end()){
    delete it->second;
    it++;
  }
}

void ConfigGroup::set(const std::string& key, ConfigGroup* el){
  std::map<std::string, ConfigGroup*>::iterator it = els.find(key);
  if(it != els.end()){
    delete it->second;
    els.erase(it);
  }

  els.insert(std::pair<std::string, ConfigGroup*>(key, el));
}

ConfigGroup* ConfigGroup::get(const std::string& key){
  std::map<std::string, ConfigGroup*>::iterator it = els.find(key);
  if(it != els.end())
    return it->second;
  else
    return NULL;
}

/* CONFIG */

void Config::buildPath(const std::string& path, std::vector<std::string>& cpath){
  //parse path
  std::string tmp;
  for(int i = 0; i < path.size(); i++){
    const char& c = path[i];
    bool end = (i == path.size()-1);

    if(c == '.'){
      cpath.push_back(tmp);
      tmp ="";
    }
    else if(end){
      tmp += c;
      cpath.push_back(tmp);
    }
    else
      tmp += c;
  }
}

bool Config::has(const std::string& path){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  int i = 0;
  while(current != NULL && i < cpath.size()){
    current = current->get(cpath[i]);
    i++;
  }

  return (i == cpath.size() && current != NULL && current->els.size() > 0
      && current->els.begin()->second == NULL);
}

const std::string& Config::get(const std::string& path){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  int i = 0;
  while(current != NULL && i < cpath.size()){
    current = current->get(cpath[i]);
    i++;
  }

  //search the value
  if(i == cpath.size() && current != NULL && current->els.size() > 0
      && current->els.begin()->second == NULL)
    return current->els.begin()->first;
  else
    return path;
}

void Config::set(const std::string& path, const std::string& value){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  for(int i = 0; i < cpath.size(); i++){
    ConfigGroup* next = current->get(cpath[i]);

    //create a new group or delete if last
    if(next == NULL || (i == cpath.size()-1)){
      next = new ConfigGroup;
      current->set(cpath[i], next);
    }

    current = next;
  }

  //set the value
  current->set(value, NULL);
}

void Config::parse(const std::string& data){
  std::string path;
  std::string tmp;
  std::string id;

  const int ID = 0;
  const int VAL = 1;

  std::string prev_id;

  int mode = ID;
  int prev_rank = 0;
  int rank = 0;
  int tab = 0;
  bool ranked = false;

  std::vector<std::string> lifo;

  for(int i = 0; i < data.size(); i++){
    const char& c = data[i];
    bool end = (i == data.size()-1);

    if(mode == ID){
      //new line, end id
      if(c == '\n' || c == '='){
        //id not null
        if(tmp.size() > 0){
          //a value
          if(c == '='){
            id = tmp;
            mode = VAL;
          }

          //rank explode
           //go highter
          if(rank > prev_rank){
            path += prev_id;
            path += ".";
            lifo.push_back(prev_id);
          }
          //go lower
          else if(rank < prev_rank){
            int diff = prev_rank-rank;
            int n = diff/tab;
            for(int j = 0; j < n; j++){
              if(lifo.size() > 0)
                prev_id = lifo[lifo.size()-1];
              path = path.substr(0, path.size()-prev_id.size()-1);
              lifo.pop_back();
            }
          }

          if(mode == ID)
            prev_id = tmp;
          prev_rank = rank;

          ranked = false;
          rank = 0;
          tmp = "";
        }
      }
      else if(c == ' ' || c == '\t'){
        //update rank
        if(!ranked)
          rank++;
      }
      else{
        if(!ranked)
          ranked = true;

        //define tab spaces fo this file
        if(tab == 0)
          tab = rank;

        tmp += c;
      }
    }
    else if(mode == VAL){
      //new value, go back to id mode
      if(c == '\n'){
        set(path+id, tmp);
        std::cout << "set " << path+id << " = " << tmp << std::endl;
        tmp ="";
        mode = ID;
      }
      else
        tmp += c;
    }
  }
}

void Config::load(const std::string& data){
  parse(data);
}

bool Config::loadFromFile(const std::string& path){
  std::ifstream file(path.c_str(), std::ios::binary);
  std::string data;
  if(file){
    //get content
    data.assign(std::istreambuf_iterator<char>(file),std::istreambuf_iterator<char>());
    parse(data);
    return true;
  }
  else
    return false;
}
<commit_msg>delete debug infos<commit_after>
#include "Config.hpp"

/* CONFIG GROUP */
ConfigGroup::~ConfigGroup(){
  clear();
}

void ConfigGroup::clear(){
  std::map<std::string, ConfigGroup*>::iterator it = els.begin();
  while(it != els.end()){
    delete it->second;
    it++;
  }
}

void ConfigGroup::set(const std::string& key, ConfigGroup* el){
  std::map<std::string, ConfigGroup*>::iterator it = els.find(key);
  if(it != els.end()){
    delete it->second;
    els.erase(it);
  }

  els.insert(std::pair<std::string, ConfigGroup*>(key, el));
}

ConfigGroup* ConfigGroup::get(const std::string& key){
  std::map<std::string, ConfigGroup*>::iterator it = els.find(key);
  if(it != els.end())
    return it->second;
  else
    return NULL;
}

/* CONFIG */

void Config::buildPath(const std::string& path, std::vector<std::string>& cpath){
  //parse path
  std::string tmp;
  for(int i = 0; i < path.size(); i++){
    const char& c = path[i];
    bool end = (i == path.size()-1);

    if(c == '.'){
      cpath.push_back(tmp);
      tmp ="";
    }
    else if(end){
      tmp += c;
      cpath.push_back(tmp);
    }
    else
      tmp += c;
  }
}

bool Config::has(const std::string& path){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  int i = 0;
  while(current != NULL && i < cpath.size()){
    current = current->get(cpath[i]);
    i++;
  }

  return (i == cpath.size() && current != NULL && current->els.size() > 0
      && current->els.begin()->second == NULL);
}

const std::string& Config::get(const std::string& path){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  int i = 0;
  while(current != NULL && i < cpath.size()){
    current = current->get(cpath[i]);
    i++;
  }

  //search the value
  if(i == cpath.size() && current != NULL && current->els.size() > 0
      && current->els.begin()->second == NULL)
    return current->els.begin()->first;
  else
    return path;
}

void Config::set(const std::string& path, const std::string& value){
  //build path
  std::vector<std::string> cpath;
  buildPath(path, cpath);

  //explode groups
  ConfigGroup* current = &root;
  for(int i = 0; i < cpath.size(); i++){
    ConfigGroup* next = current->get(cpath[i]);

    //create a new group or delete if last
    if(next == NULL || (i == cpath.size()-1)){
      next = new ConfigGroup;
      current->set(cpath[i], next);
    }

    current = next;
  }

  //set the value
  current->set(value, NULL);
}

void Config::parse(const std::string& data){
  std::string path;
  std::string tmp;
  std::string id;

  const int ID = 0;
  const int VAL = 1;

  std::string prev_id;

  int mode = ID;
  int prev_rank = 0;
  int rank = 0;
  int tab = 0;
  bool ranked = false;

  std::vector<std::string> lifo;

  for(int i = 0; i < data.size(); i++){
    const char& c = data[i];
    bool end = (i == data.size()-1);

    if(mode == ID){
      //new line, end id
      if(c == '\n' || c == '='){
        //id not null
        if(tmp.size() > 0){
          //a value
          if(c == '='){
            id = tmp;
            mode = VAL;
          }

          //rank explode
           //go highter
          if(rank > prev_rank){
            path += prev_id;
            path += ".";
            lifo.push_back(prev_id);
          }
          //go lower
          else if(rank < prev_rank){
            int diff = prev_rank-rank;
            int n = diff/tab;
            for(int j = 0; j < n; j++){
              if(lifo.size() > 0)
                prev_id = lifo[lifo.size()-1];
              path = path.substr(0, path.size()-prev_id.size()-1);
              lifo.pop_back();
            }
          }

          if(mode == ID)
            prev_id = tmp;
          prev_rank = rank;

          ranked = false;
          rank = 0;
          tmp = "";
        }
      }
      else if(c == ' ' || c == '\t'){
        //update rank
        if(!ranked)
          rank++;
      }
      else{
        if(!ranked)
          ranked = true;

        //define tab spaces fo this file
        if(tab == 0)
          tab = rank;

        tmp += c;
      }
    }
    else if(mode == VAL){
      //new value, go back to id mode
      if(c == '\n'){
        set(path+id, tmp);
        tmp ="";
        mode = ID;
      }
      else
        tmp += c;
    }
  }
}

void Config::load(const std::string& data){
  parse(data);
}

bool Config::loadFromFile(const std::string& path){
  std::ifstream file(path.c_str(), std::ios::binary);
  std::string data;
  if(file){
    //get content
    data.assign(std::istreambuf_iterator<char>(file),std::istreambuf_iterator<char>());
    parse(data);
    return true;
  }
  else
    return false;
}
<|endoftext|>


<commit_before>/******************************************************************************
    Coords.h

  Coordinate values (x, y, z, width, height ) wrapper

  Copyright (c) 2013 Jeffrey Carpenter
  All rights reserved.

******************************************************************************/
#ifndef NOMLIB_COORDS_HEADERS
#define NOMLIB_COORDS_HEADERS

#include <iostream>
#include <string>
#include <map>

#include "SDL.h"

#include "gamelib.h"

namespace nom
{
  class Coords
  {
    public:
      Coords ( void );

      Coords ( signed int x_, signed int y_,
                signed int width_ = 0, signed height_ = 0);

      ~Coords ( void );

      // phase out
      void setCoords (  signed int x_, signed int y_,
                        signed int width_ = 0, signed int height_ = 0 );

      SDL_Rect getSDL_Rect ( void ) const;

      signed int getX ( void ) const;
      signed int getY ( void ) const;
      void setX ( signed int x_ );
      void setY ( signed int y_ );
      void setXY ( signed int x_, signed int y_ );

      signed int getWidth ( void ) const;
      signed int getHeight ( void ) const;

      void setWidth ( signed int width_ );
      void setHeight ( signed int height_ );

      // phase out
      void setDimensions ( signed int width_, signed int height_ );

      void updateX ( signed int x_ );
      void updateY ( signed int y_ );
      void updateXY ( signed int x_ = 0, signed int y_ = 0 );

      void updateWidth ( signed int width_ );
      void updateHeight ( signed int height_ );

      void updateCoords ( signed int x_ = 0, signed int y_ = 0, signed int width_ = 0, signed int height_ = 0 );

      signed int x;
      signed int y;
      signed int z; // reserved
      signed int width;
      signed int height;

    private:
      // ...
  };

  // FIXME: not sure why these cannot be put into the class file without
  // linking errs?
  inline bool operator == ( const nom::Coords& left, const nom::Coords& right )
  {
    return (left.x == right.x ) &&
           (left.y == right.y ) &&
           (left.width == right.width ) &&
           (left.height == right.height );
  }

  inline bool operator != ( const nom::Coords& left, const nom::Coords& right )
  {
    return ! ( left == right );
  }

  inline nom::Coords operator + ( const nom::Coords& left, const nom::Coords& right )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x + right.x ),
                          static_cast<int32_t> ( left.y + right.y ),
                          static_cast<int32_t> ( left.width + right.width ),
                          static_cast<int32_t> ( left.height + right.height )
                        );
  }

  inline nom::Coords operator ++ ( nom::Coords& left )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x ++ ),
                          static_cast<int32_t> ( left.y ++ ),
                          static_cast<int32_t> ( left.width ++ ),
                          static_cast<int32_t> ( left.height ++ )
                        );
  }

  inline nom::Coords operator - ( const nom::Coords& left, const nom::Coords& right )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x - right.x ),
                          static_cast<int32_t> ( left.y - right.y ),
                          static_cast<int32_t> ( left.width - right.width ),
                          static_cast<int32_t> ( left.height - right.height )
                        );
  }

  inline nom::Coords operator -- ( nom::Coords& left )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x -- ),
                          static_cast<int32_t> ( left.y -- ),
                          static_cast<int32_t> ( left.width -- ),
                          static_cast<int32_t> ( left.height -- )
                        );
  }

  inline nom::Coords operator * ( const nom::Coords& left, const nom::Coords& right)
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x * right.x ),
                          static_cast<int32_t> ( left.y * right.y ),
                          static_cast<int32_t> ( left.width * right.width ),
                          static_cast<int32_t> ( left.height * right.height )
                        );
  }

  inline nom::Coords& operator += ( nom::Coords& left, const nom::Coords& right)
  {
    return left = left + right;
  }

  inline nom::Coords& operator -= ( nom::Coords& left, const nom::Coords& right )
  {
    return left = left - right;
  }

  inline nom::Coords& operator *= ( nom::Coords& left, const nom::Coords& right)
  {
    return left = left * right;
  }
}

#endif // NOMLIB_COORDS_HEADERS defined
<commit_msg>Added comparison operator for division of two nom::Coords<commit_after>/******************************************************************************
    Coords.h

  Coordinate values (x, y, z, width, height ) wrapper

  Copyright (c) 2013 Jeffrey Carpenter
  All rights reserved.

******************************************************************************/
#ifndef NOMLIB_COORDS_HEADERS
#define NOMLIB_COORDS_HEADERS

#include <iostream>
#include <string>
#include <map>

#include "SDL.h"

#include "gamelib.h"

namespace nom
{
  class Coords
  {
    public:
      Coords ( void );

      Coords ( signed int x_, signed int y_,
                signed int width_ = 0, signed height_ = 0);

      ~Coords ( void );

      // phase out
      void setCoords (  signed int x_, signed int y_,
                        signed int width_ = 0, signed int height_ = 0 );

      SDL_Rect getSDL_Rect ( void ) const;

      signed int getX ( void ) const;
      signed int getY ( void ) const;
      void setX ( signed int x_ );
      void setY ( signed int y_ );
      void setXY ( signed int x_, signed int y_ );

      signed int getWidth ( void ) const;
      signed int getHeight ( void ) const;

      void setWidth ( signed int width_ );
      void setHeight ( signed int height_ );

      // phase out
      void setDimensions ( signed int width_, signed int height_ );

      void updateX ( signed int x_ );
      void updateY ( signed int y_ );
      void updateXY ( signed int x_ = 0, signed int y_ = 0 );

      void updateWidth ( signed int width_ );
      void updateHeight ( signed int height_ );

      void updateCoords ( signed int x_ = 0, signed int y_ = 0, signed int width_ = 0, signed int height_ = 0 );

      signed int x;
      signed int y;
      signed int z; // reserved
      signed int width;
      signed int height;

    private:
      // ...
  };

  // FIXME: not sure why these cannot be put into the class file without
  // linking errs?
  inline bool operator == ( const nom::Coords& left, const nom::Coords& right )
  {
    return (left.x == right.x ) &&
           (left.y == right.y ) &&
           (left.width == right.width ) &&
           (left.height == right.height );
  }

  inline bool operator != ( const nom::Coords& left, const nom::Coords& right )
  {
    return ! ( left == right );
  }

  inline nom::Coords operator + ( const nom::Coords& left, const nom::Coords& right )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x + right.x ),
                          static_cast<int32_t> ( left.y + right.y ),
                          static_cast<int32_t> ( left.width + right.width ),
                          static_cast<int32_t> ( left.height + right.height )
                        );
  }

  inline nom::Coords operator ++ ( nom::Coords& left )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x ++ ),
                          static_cast<int32_t> ( left.y ++ ),
                          static_cast<int32_t> ( left.width ++ ),
                          static_cast<int32_t> ( left.height ++ )
                        );
  }

  inline nom::Coords operator - ( const nom::Coords& left, const nom::Coords& right )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x - right.x ),
                          static_cast<int32_t> ( left.y - right.y ),
                          static_cast<int32_t> ( left.width - right.width ),
                          static_cast<int32_t> ( left.height - right.height )
                        );
  }

  inline nom::Coords operator -- ( nom::Coords& left )
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x -- ),
                          static_cast<int32_t> ( left.y -- ),
                          static_cast<int32_t> ( left.width -- ),
                          static_cast<int32_t> ( left.height -- )
                        );
  }

  inline nom::Coords operator * ( const nom::Coords& left, const nom::Coords& right)
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x * right.x ),
                          static_cast<int32_t> ( left.y * right.y ),
                          static_cast<int32_t> ( left.width * right.width ),
                          static_cast<int32_t> ( left.height * right.height )
                        );
  }

  inline nom::Coords operator / ( const nom::Coords& left, const nom::Coords& right)
  {
    return nom::Coords  ( static_cast<int32_t> ( left.x / right.x ),
                          static_cast<int32_t> ( left.y / right.y ),
                          static_cast<int32_t> ( left.width / right.width ),
                          static_cast<int32_t> ( left.height / right.height )
                        );
  }

  inline nom::Coords& operator += ( nom::Coords& left, const nom::Coords& right)
  {
    return left = left + right;
  }

  inline nom::Coords& operator -= ( nom::Coords& left, const nom::Coords& right )
  {
    return left = left - right;
  }

  inline nom::Coords& operator *= ( nom::Coords& left, const nom::Coords& right)
  {
    return left = left * right;
  }
}

#endif // NOMLIB_COORDS_HEADERS defined
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "knob.h"

#include <QBrush>
#include <QGraphicsSceneTouchEvent>

Knob::Knob()
    : QGraphicsEllipseItem(-50, -50, 100, 100)
{
    setAcceptTouchEvents(true);
    setBrush(Qt::lightGray);

    QGraphicsEllipseItem *leftItem = new QGraphicsEllipseItem(0, 0, 10, 10, this);
    leftItem->setPos(-45, -5);
    leftItem->setBrush(Qt::darkGreen);

    QGraphicsEllipseItem *rightItem = new QGraphicsEllipseItem(0, 0, 10, 10, this);
    rightItem->setPos(35, -5);
    rightItem->setBrush(Qt::darkRed);
}

bool Knob::sceneEvent(QEvent *event)
{
    switch (event->type()) {
    case QEvent::GraphicsSceneTouchBegin:
        event->accept();
        break;

    case QEvent::GraphicsSceneTouchUpdate:
    case QEvent::GraphicsSceneTouchEnd:
    {
        QGraphicsSceneTouchEvent *touchEvent = static_cast<QGraphicsSceneTouchEvent *>(event);

        if (touchEvent->touchPoints().count() == 2) {
            QGraphicsSceneTouchEvent::TouchPoint *touchPoint1 = touchEvent->touchPoints().first();
            QGraphicsSceneTouchEvent::TouchPoint *touchPoint2 = touchEvent->touchPoints().last();

            QLineF line1(touchPoint1->lastScenePos(), touchPoint2->lastScenePos());
            QLineF line2(touchPoint1->scenePos(), touchPoint2->scenePos());

            rotate(line2.angleTo(line1));
        }

        touchEvent->accept();
        break;
    }

    default:
        return QGraphicsItem::sceneEvent(event);
    }

    return true;
}
<commit_msg>make the red and green children items larger<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "knob.h"

#include <QBrush>
#include <QGraphicsSceneTouchEvent>

Knob::Knob()
    : QGraphicsEllipseItem(-50, -50, 100, 100)
{
    setAcceptTouchEvents(true);
    setBrush(Qt::lightGray);

    QGraphicsEllipseItem *leftItem = new QGraphicsEllipseItem(0, 0, 20, 20, this);
    leftItem->setPos(-40, -10);
    leftItem->setBrush(Qt::darkGreen);

    QGraphicsEllipseItem *rightItem = new QGraphicsEllipseItem(0, 0, 20, 20, this);
    rightItem->setPos(20, -10);
    rightItem->setBrush(Qt::darkRed);
}

bool Knob::sceneEvent(QEvent *event)
{
    switch (event->type()) {
    case QEvent::GraphicsSceneTouchBegin:
        event->accept();
        break;

    case QEvent::GraphicsSceneTouchUpdate:
    case QEvent::GraphicsSceneTouchEnd:
    {
        QGraphicsSceneTouchEvent *touchEvent = static_cast<QGraphicsSceneTouchEvent *>(event);

        if (touchEvent->touchPoints().count() == 2) {
            QGraphicsSceneTouchEvent::TouchPoint *touchPoint1 = touchEvent->touchPoints().first();
            QGraphicsSceneTouchEvent::TouchPoint *touchPoint2 = touchEvent->touchPoints().last();

            QLineF line1(touchPoint1->lastScenePos(), touchPoint2->lastScenePos());
            QLineF line2(touchPoint1->scenePos(), touchPoint2->scenePos());

            rotate(line2.angleTo(line1));
        }

        touchEvent->accept();
        break;
    }

    default:
        return QGraphicsItem::sceneEvent(event);
    }

    return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h"
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"

using namespace mbed;

QUECTEL_BG96_CellularNetwork::QUECTEL_BG96_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
{
}

QUECTEL_BG96_CellularNetwork::~QUECTEL_BG96_CellularNetwork()
{
}

bool QUECTEL_BG96_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
{
    if ((requested_stack == IPV4_STACK) ||
        (requested_stack == IPV6_STACK) ||
        (requested_stack == IPV4V6_STACK)) {
        return true;
    }

    return false;
}

NetworkStack *QUECTEL_BG96_CellularNetwork::get_stack()
{
    if (!_stack) {
        _stack = new QUECTEL_BG96_CellularStack(_at, _cid, _ip_stack_type);
    }
    return _stack;
}

nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
{
    _at.lock();

    switch (opsAct) {
        case RAT_CATM1:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",0,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        case RAT_NB1:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",030201");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",1,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        case RAT_GSM:
        case RAT_GSM_COMPACT:
        case RAT_UTRAN:
        case RAT_EGPRS:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",010203");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",1,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        default:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",0,1"); //auto mode
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",2,1"); //auto mode
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.unlock();
            _op_act = RAT_UNKNOWN;
            return NSAPI_ERROR_UNSUPPORTED;
    }

    return _at.unlock_return_error();
}
<commit_msg>Cellular: BG96 remove IPv6 stack support<commit_after>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h"
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"

using namespace mbed;

QUECTEL_BG96_CellularNetwork::QUECTEL_BG96_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
{
}

QUECTEL_BG96_CellularNetwork::~QUECTEL_BG96_CellularNetwork()
{
}

bool QUECTEL_BG96_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
{
    if (requested_stack == IPV4_STACK) {
        return true;
    }

    return false;
}

NetworkStack *QUECTEL_BG96_CellularNetwork::get_stack()
{
    if (!_stack) {
        _stack = new QUECTEL_BG96_CellularStack(_at, _cid, _ip_stack_type);
    }
    return _stack;
}

nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
{
    _at.lock();

    switch (opsAct) {
        case RAT_CATM1:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",0,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        case RAT_NB1:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",030201");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",3,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",1,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        case RAT_GSM:
        case RAT_GSM_COMPACT:
        case RAT_UTRAN:
        case RAT_EGPRS:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",010203");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",1,1");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            break;
        default:
            _at.cmd_start("AT+QCFG=\"nwscanseq\",020301");
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"nwscanmode\",0,1"); //auto mode
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.cmd_start("AT+QCFG=\"iotopmode\",2,1"); //auto mode
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();
            _at.unlock();
            _op_act = RAT_UNKNOWN;
            return NSAPI_ERROR_UNSUPPORTED;
    }

    return _at.unlock_return_error();
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Config.h"
#include "Device.h"
#include "Filesystem.h"
#include "InputManager.h"
#include "Log.h"
#include "OS.h"
#include "Renderer.h"
#include "DebugRenderer.h"
#include "Types.h"
#include "String.h"
#include "Args.h"
#include "Game.h"
#include <cstdlib>
#include "ArchiveResourceArchive.h"
#include "FileResourceArchive.h"
#include "ResourceManager.h"
#include "TextureResource.h"

#ifdef CROWN_BUILD_OPENGL
	#include "renderers/gl/GLRenderer.h"
#endif

#ifdef CROWN_BUILD_OPENGLES
	#include "renderers/gles/GLESRenderer.h"
#endif

namespace crown
{

static const char* GAME_LIBRARY_NAME = "libgame.so";

//-----------------------------------------------------------------------------
Device::Device() :
	m_preferred_window_width(1000),
	m_preferred_window_height(625),
	m_preferred_window_fullscreen(0),
	m_preferred_renderer(RENDERER_GL),
	m_preferred_mode(MODE_RELEASE),

	m_is_init(false),
	m_is_running(false),

	m_frame_count(0),

	m_last_time(0),
	m_current_time(0),
	m_last_delta_time(0.0f),

	m_filesystem(NULL),
	m_resource_manager(NULL),
	m_input_manager(NULL),
	m_renderer(NULL),
	m_debug_renderer(NULL),

	m_resource_archive(NULL),

	m_game(NULL),
	m_game_library(NULL)
{
	string::strcpy(m_preferred_root_path, string::EMPTY);
	string::strcpy(m_preferred_user_path, string::EMPTY);
}

//-----------------------------------------------------------------------------
Device::~Device()
{
}

//-----------------------------------------------------------------------------
bool Device::init(int argc, char** argv)
{
	if (is_init())
	{
		Log::e("Crown Engine is already initialized.");
		return false;
	}

	if (parse_command_line(argc, argv) == false)
	{
		return false;
	}

	// Initialize
	Log::i("Initializing Crown Engine %d.%d.%d...", CROWN_VERSION_MAJOR, CROWN_VERSION_MINOR, CROWN_VERSION_MICRO);

	create_filesystem();

	create_resource_manager();

	create_input_manager();

	create_renderer();

	create_debug_renderer();

	Log::i("Crown Engine initialized.");

	Log::i("Initializing Game...");

	const char* game_library_path = m_filesystem->build_os_path(m_filesystem->root_path(), GAME_LIBRARY_NAME);
	m_game_library = os::open_library(game_library_path);

	if (m_game_library == NULL)
	{
		Log::e("Unable to load the game.");
		return false;
	}

	create_game_t* create_game = (create_game_t*)os::lookup_symbol(m_game_library, "create_game");

	m_game = create_game();

	m_game->init();

	m_is_init = true;

	start();

	return true;
}

//-----------------------------------------------------------------------------
void Device::shutdown()
{
	if (is_init() == false)
	{
		Log::e("Crown Engine is not initialized.");
		return;
	}

	m_game->shutdown();

	destroy_game_t* destroy_game = (destroy_game_t*)os::lookup_symbol(m_game_library, "destroy_game");

	destroy_game(m_game);
	m_game = NULL;

	os::close_library(m_game_library);

	if (m_input_manager)
	{
		delete m_input_manager;
	}

	Log::i("Releasing Renderer...");

	if (m_renderer)
	{
		delete m_renderer;
	}

	Log::i("Releasing DebugRenderer...");
	if (m_debug_renderer)
	{
		delete m_debug_renderer;
	}

	Log::i("Releasing ResourceManager...");
	if (m_resource_archive)
	{
		delete m_resource_archive;
	}

	if (m_resource_manager)
	{
		delete m_resource_manager;
	}

	Log::i("Releasing Filesystem...");

	if (m_filesystem)
	{
		delete m_filesystem;
	}

	m_is_init = false;
}

//-----------------------------------------------------------------------------
bool Device::is_init() const
{
	return m_is_init;
}

//-----------------------------------------------------------------------------
Filesystem* Device::filesystem()
{
	return m_filesystem;
}

//-----------------------------------------------------------------------------
ResourceManager* Device::resource_manager()
{
	return m_resource_manager;
}

//-----------------------------------------------------------------------------
InputManager* Device::input_manager()
{
	return m_input_manager;
}

//-----------------------------------------------------------------------------
Renderer* Device::renderer()
{
	return m_renderer;
}

//-----------------------------------------------------------------------------
DebugRenderer* Device::debug_renderer()
{
	return m_debug_renderer;
}

//-----------------------------------------------------------------------------
void Device::start()
{
	if (is_init() == false)
	{
		Log::e("Cannot start uninitialized engine.");
		return;
	}

	m_is_running = true;

	m_last_time = os::milliseconds();
}

//-----------------------------------------------------------------------------
void Device::stop()
{
	if (is_init() == false)
	{
		Log::e("Cannot stop uninitialized engine.");
		return;
	}

	m_is_running = false;
}

//-----------------------------------------------------------------------------
bool Device::is_running() const
{
	return m_is_running;
}

//-----------------------------------------------------------------------------
uint64_t Device::frame_count() const
{
	return m_frame_count;
}

//-----------------------------------------------------------------------------
float Device::last_delta_time() const
{
	return m_last_delta_time;
}

//-----------------------------------------------------------------------------
void Device::frame()
{
	m_current_time = os::milliseconds();
	m_last_delta_time = (m_current_time - m_last_time) / 1000.0f;
	m_last_time = m_current_time;

	if (frame_count() % 5 == 0)
	{
		m_resource_manager->flush_load_queue();
		m_resource_manager->bring_loaded_online();
	}

	m_input_manager->event_loop();

	m_renderer->begin_frame();

	m_game->update(last_delta_time());

	m_debug_renderer->draw_all();

	m_renderer->end_frame();

	m_frame_count++;
}

//-----------------------------------------------------------------------------
ResourceId Device::load(const char* name)
{
	return m_resource_manager->load(name);
}

//-----------------------------------------------------------------------------
void Device::unload(ResourceId name)
{
	m_resource_manager->unload(name);
}

//-----------------------------------------------------------------------------
void Device::reload(ResourceId name)
{
	m_resource_manager->reload(name);
	m_renderer->reload_texture(name);
}

//-----------------------------------------------------------------------------
bool Device::is_loaded(ResourceId name)
{
	return m_resource_manager->is_loaded(name);
}

//-----------------------------------------------------------------------------
const void* Device::data(ResourceId name)
{
	return m_resource_manager->data(name);
}

//-----------------------------------------------------------------------------
void Device::create_filesystem()
{
	// Select current dir if no root path provided
	if (string::strcmp(m_preferred_root_path, string::EMPTY) == 0)
	{
		m_filesystem = new Filesystem(os::get_cwd());
	}
	else
	{
		m_filesystem = new Filesystem(m_preferred_root_path);
	}
}

//-----------------------------------------------------------------------------
void Device::create_resource_manager()
{
	// Select appropriate resource archive
	if (m_preferred_mode == MODE_DEVELOPMENT)
	{
		m_resource_archive = new FileResourceArchive(*m_filesystem);
	}
	else
	{
		m_resource_archive = new ArchiveResourceArchive(*m_filesystem);
	}

	// Create resource manager
	m_resource_manager = new ResourceManager(*m_resource_archive, m_resource_allocator);
}

//-----------------------------------------------------------------------------
void Device::create_input_manager()
{
	// Create input manager
	m_input_manager = new InputManager();
}

//-----------------------------------------------------------------------------
void Device::create_renderer()
{
	// Select appropriate renderer
	if (m_preferred_renderer == RENDERER_GL)
	{
		#ifdef CROWN_BUILD_OPENGL
		m_renderer = new GLRenderer;
		#else
		Log::e("Crown Engine was not built with OpenGL support.");
		assert(false);
		#endif
	}
	else if (m_preferred_renderer == RENDERER_GLES)
	{
		#ifdef CROWN_BUILD_OPENGLES
		m_renderer = new GLESRenderer;
		#else
		Log::e("Crown Engine was not built with OpenGL|ES support.");
		assert(false);
		#endif
	}
}

//-----------------------------------------------------------------------------
void Device::create_debug_renderer()
{
	// Create debug renderer
	m_debug_renderer = new DebugRenderer(*m_renderer);
}

//-----------------------------------------------------------------------------
bool Device::parse_command_line(int argc, char** argv)
{
	ArgsOption options[] =
	{
		"help",       AOA_NO_ARGUMENT,       NULL,        'i',
		"root-path",  AOA_REQUIRED_ARGUMENT, NULL,        'r',
		"user-path",  AOA_REQUIRED_ARGUMENT, NULL,        'u',
		"width",      AOA_REQUIRED_ARGUMENT, NULL,        'w',
		"height",     AOA_REQUIRED_ARGUMENT, NULL,        'h',
		"fullscreen", AOA_NO_ARGUMENT,       &m_preferred_window_fullscreen, 1,
		"gl",         AOA_NO_ARGUMENT,       &m_preferred_renderer, RENDERER_GL,
		"gles",       AOA_NO_ARGUMENT,       &m_preferred_renderer, RENDERER_GLES,
		"dev",        AOA_NO_ARGUMENT,       &m_preferred_mode, MODE_DEVELOPMENT,
		NULL, 0, NULL, 0
	};

	Args args(argc, argv, "", options);

	while (1)
	{
		int32_t ret = args.next_option();

		switch (ret)
		{
			case -1:
			{
				return true;
			}
			// Help
			case 'i':
			{
				print_help_message();
				return false;
			}
			// Root path
			case 'r':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing absolute path after `-root-path`\n", argv[0]);
					return false;
				}
				if (!os::is_absolute_path(args.option_argument()))
				{
					os::printf("%s: error: the root path must be absolute.\n", argv[0]);
					return false;
				}

				string::strcpy(m_preferred_root_path, args.option_argument());

				break;
			}
			// User path
			case 'u':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing absolute path after `--user-path`\n", argv[0]);
					return false;
				}
				if (!os::is_absolute_path(args.option_argument()))
				{
					os::printf("%s: error: the user path must be absolute.\n", argv[0]);
					return false;
				}

				string::strcpy(m_preferred_user_path, args.option_argument());

				break;
			}
			// Window width
			case 'w':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing width value after `--width`\n", argv[0]);
					return false;
				}

				m_preferred_window_width = atoi(args.option_argument());
				break;
			}
			// Window height
			case 'h':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing height value after `--height`\n", argv[0]);
					return false;
				}

				m_preferred_window_height = atoi(args.option_argument());
				break;
			}
			default:
			{
				break;
			}
		}
	}

	return true;
}

//-----------------------------------------------------------------------------
void Device::print_help_message()
{
	os::printf(
	"Usage: crown [options]\n"
	"Options:\n\n"

	"All of the following options take precedence over\n"
	"environment variables and configuration files.\n\n"

	"  --help                Show this help.\n"
	"  --root-path <path>    Use <path> as the filesystem root path.\n"
	"  --user-path <path>    Use <path> as the filesystem user path.\n"
	"  --width <width>       Set the <width> of the render window.\n"
	"  --height <width>      Set the <height> of the render window.\n"
	"  --fullscreen          Start in fullscreen.\n"
	"  --gl                  Use OpenGL as rendering backend.\n"
	"  --gles                Use OpenGL|ES as rendering backend.\n"
	"  --dev                 Run the engine in development mode\n");
}

Device g_device;
Device* device()
{
	return &g_device;
}

} // namespace crown

<commit_msg>Use new ResourceManager APIs<commit_after>/*
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Config.h"
#include "Device.h"
#include "Filesystem.h"
#include "InputManager.h"
#include "Log.h"
#include "OS.h"
#include "Renderer.h"
#include "DebugRenderer.h"
#include "Types.h"
#include "String.h"
#include "Args.h"
#include "Game.h"
#include <cstdlib>
#include "ArchiveResourceArchive.h"
#include "FileResourceArchive.h"
#include "ResourceManager.h"
#include "TextureResource.h"

#ifdef CROWN_BUILD_OPENGL
	#include "renderers/gl/GLRenderer.h"
#endif

#ifdef CROWN_BUILD_OPENGLES
	#include "renderers/gles/GLESRenderer.h"
#endif

namespace crown
{

static const char* GAME_LIBRARY_NAME = "libgame.so";

//-----------------------------------------------------------------------------
Device::Device() :
	m_preferred_window_width(1000),
	m_preferred_window_height(625),
	m_preferred_window_fullscreen(0),
	m_preferred_renderer(RENDERER_GL),
	m_preferred_mode(MODE_RELEASE),

	m_is_init(false),
	m_is_running(false),

	m_frame_count(0),

	m_last_time(0),
	m_current_time(0),
	m_last_delta_time(0.0f),

	m_filesystem(NULL),
	m_resource_manager(NULL),
	m_input_manager(NULL),
	m_renderer(NULL),
	m_debug_renderer(NULL),

	m_resource_archive(NULL),

	m_game(NULL),
	m_game_library(NULL)
{
	string::strcpy(m_preferred_root_path, string::EMPTY);
	string::strcpy(m_preferred_user_path, string::EMPTY);
}

//-----------------------------------------------------------------------------
Device::~Device()
{
}

//-----------------------------------------------------------------------------
bool Device::init(int argc, char** argv)
{
	if (is_init())
	{
		Log::e("Crown Engine is already initialized.");
		return false;
	}

	if (parse_command_line(argc, argv) == false)
	{
		return false;
	}

	// Initialize
	Log::i("Initializing Crown Engine %d.%d.%d...", CROWN_VERSION_MAJOR, CROWN_VERSION_MINOR, CROWN_VERSION_MICRO);

	create_filesystem();

	create_resource_manager();

	create_input_manager();

	create_renderer();

	create_debug_renderer();

	Log::i("Crown Engine initialized.");

	Log::i("Initializing Game...");

	const char* game_library_path = m_filesystem->build_os_path(m_filesystem->root_path(), GAME_LIBRARY_NAME);
	m_game_library = os::open_library(game_library_path);

	if (m_game_library == NULL)
	{
		Log::e("Unable to load the game.");
		return false;
	}

	create_game_t* create_game = (create_game_t*)os::lookup_symbol(m_game_library, "create_game");

	m_game = create_game();

	m_game->init();

	m_is_init = true;

	start();

	return true;
}

//-----------------------------------------------------------------------------
void Device::shutdown()
{
	if (is_init() == false)
	{
		Log::e("Crown Engine is not initialized.");
		return;
	}

	m_game->shutdown();

	destroy_game_t* destroy_game = (destroy_game_t*)os::lookup_symbol(m_game_library, "destroy_game");

	destroy_game(m_game);
	m_game = NULL;

	os::close_library(m_game_library);

	if (m_input_manager)
	{
		delete m_input_manager;
	}

	Log::i("Releasing Renderer...");

	if (m_renderer)
	{
		delete m_renderer;
	}

	Log::i("Releasing DebugRenderer...");
	if (m_debug_renderer)
	{
		delete m_debug_renderer;
	}

	Log::i("Releasing ResourceManager...");
	if (m_resource_archive)
	{
		delete m_resource_archive;
	}

	if (m_resource_manager)
	{
		delete m_resource_manager;
	}

	Log::i("Releasing Filesystem...");

	if (m_filesystem)
	{
		delete m_filesystem;
	}

	m_is_init = false;
}

//-----------------------------------------------------------------------------
bool Device::is_init() const
{
	return m_is_init;
}

//-----------------------------------------------------------------------------
Filesystem* Device::filesystem()
{
	return m_filesystem;
}

//-----------------------------------------------------------------------------
ResourceManager* Device::resource_manager()
{
	return m_resource_manager;
}

//-----------------------------------------------------------------------------
InputManager* Device::input_manager()
{
	return m_input_manager;
}

//-----------------------------------------------------------------------------
Renderer* Device::renderer()
{
	return m_renderer;
}

//-----------------------------------------------------------------------------
DebugRenderer* Device::debug_renderer()
{
	return m_debug_renderer;
}

//-----------------------------------------------------------------------------
void Device::start()
{
	if (is_init() == false)
	{
		Log::e("Cannot start uninitialized engine.");
		return;
	}

	m_is_running = true;

	m_last_time = os::milliseconds();
}

//-----------------------------------------------------------------------------
void Device::stop()
{
	if (is_init() == false)
	{
		Log::e("Cannot stop uninitialized engine.");
		return;
	}

	m_is_running = false;
}

//-----------------------------------------------------------------------------
bool Device::is_running() const
{
	return m_is_running;
}

//-----------------------------------------------------------------------------
uint64_t Device::frame_count() const
{
	return m_frame_count;
}

//-----------------------------------------------------------------------------
float Device::last_delta_time() const
{
	return m_last_delta_time;
}

//-----------------------------------------------------------------------------
void Device::frame()
{
	m_current_time = os::milliseconds();
	m_last_delta_time = (m_current_time - m_last_time) / 1000.0f;
	m_last_time = m_current_time;

	m_resource_manager->check_load_queue();
	m_resource_manager->bring_loaded_online();

	m_input_manager->event_loop();

	m_renderer->begin_frame();

	m_game->update(last_delta_time());

	m_debug_renderer->draw_all();

	m_renderer->end_frame();

	m_frame_count++;
}

//-----------------------------------------------------------------------------
ResourceId Device::load(const char* name)
{
	return m_resource_manager->load(name);
}

//-----------------------------------------------------------------------------
void Device::unload(ResourceId name)
{
	m_resource_manager->unload(name);
}

//-----------------------------------------------------------------------------
void Device::reload(ResourceId name)
{
	const void* old_resource = m_resource_manager->data(name);

	m_resource_manager->reload(name);

	const void* new_resource = m_resource_manager->data(name);

	if (name.type == m_resource_manager->m_texture_hash)
	{
		m_renderer->reload_texture((TextureResource*)old_resource, (TextureResource*)new_resource);
	}
}

//-----------------------------------------------------------------------------
bool Device::is_loaded(ResourceId name)
{
	return m_resource_manager->is_loaded(name);
}

//-----------------------------------------------------------------------------
const void* Device::data(ResourceId name)
{
	return m_resource_manager->data(name);
}

//-----------------------------------------------------------------------------
void Device::create_filesystem()
{
	// Select current dir if no root path provided
	if (string::strcmp(m_preferred_root_path, string::EMPTY) == 0)
	{
		m_filesystem = new Filesystem(os::get_cwd());
	}
	else
	{
		m_filesystem = new Filesystem(m_preferred_root_path);
	}
}

//-----------------------------------------------------------------------------
void Device::create_resource_manager()
{
	// Select appropriate resource archive
	if (m_preferred_mode == MODE_DEVELOPMENT)
	{
		m_resource_archive = new FileResourceArchive(*m_filesystem);
	}
	else
	{
		m_resource_archive = new ArchiveResourceArchive(*m_filesystem);
	}

	// Create resource manager
	m_resource_manager = new ResourceManager(*m_resource_archive, m_resource_allocator);
}

//-----------------------------------------------------------------------------
void Device::create_input_manager()
{
	// Create input manager
	m_input_manager = new InputManager();
}

//-----------------------------------------------------------------------------
void Device::create_renderer()
{
	// Select appropriate renderer
	if (m_preferred_renderer == RENDERER_GL)
	{
		#ifdef CROWN_BUILD_OPENGL
		m_renderer = new GLRenderer;
		#else
		Log::e("Crown Engine was not built with OpenGL support.");
		assert(false);
		#endif
	}
	else if (m_preferred_renderer == RENDERER_GLES)
	{
		#ifdef CROWN_BUILD_OPENGLES
		m_renderer = new GLESRenderer;
		#else
		Log::e("Crown Engine was not built with OpenGL|ES support.");
		assert(false);
		#endif
	}
}

//-----------------------------------------------------------------------------
void Device::create_debug_renderer()
{
	// Create debug renderer
	m_debug_renderer = new DebugRenderer(*m_renderer);
}

//-----------------------------------------------------------------------------
bool Device::parse_command_line(int argc, char** argv)
{
	ArgsOption options[] =
	{
		"help",       AOA_NO_ARGUMENT,       NULL,        'i',
		"root-path",  AOA_REQUIRED_ARGUMENT, NULL,        'r',
		"user-path",  AOA_REQUIRED_ARGUMENT, NULL,        'u',
		"width",      AOA_REQUIRED_ARGUMENT, NULL,        'w',
		"height",     AOA_REQUIRED_ARGUMENT, NULL,        'h',
		"fullscreen", AOA_NO_ARGUMENT,       &m_preferred_window_fullscreen, 1,
		"gl",         AOA_NO_ARGUMENT,       &m_preferred_renderer, RENDERER_GL,
		"gles",       AOA_NO_ARGUMENT,       &m_preferred_renderer, RENDERER_GLES,
		"dev",        AOA_NO_ARGUMENT,       &m_preferred_mode, MODE_DEVELOPMENT,
		NULL, 0, NULL, 0
	};

	Args args(argc, argv, "", options);

	while (1)
	{
		int32_t ret = args.next_option();

		switch (ret)
		{
			case -1:
			{
				return true;
			}
			// Help
			case 'i':
			{
				print_help_message();
				return false;
			}
			// Root path
			case 'r':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing absolute path after `-root-path`\n", argv[0]);
					return false;
				}
				if (!os::is_absolute_path(args.option_argument()))
				{
					os::printf("%s: error: the root path must be absolute.\n", argv[0]);
					return false;
				}

				string::strcpy(m_preferred_root_path, args.option_argument());

				break;
			}
			// User path
			case 'u':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing absolute path after `--user-path`\n", argv[0]);
					return false;
				}
				if (!os::is_absolute_path(args.option_argument()))
				{
					os::printf("%s: error: the user path must be absolute.\n", argv[0]);
					return false;
				}

				string::strcpy(m_preferred_user_path, args.option_argument());

				break;
			}
			// Window width
			case 'w':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing width value after `--width`\n", argv[0]);
					return false;
				}

				m_preferred_window_width = atoi(args.option_argument());
				break;
			}
			// Window height
			case 'h':
			{
				if (args.option_argument() == NULL)
				{
					os::printf("%s: error: missing height value after `--height`\n", argv[0]);
					return false;
				}

				m_preferred_window_height = atoi(args.option_argument());
				break;
			}
			default:
			{
				break;
			}
		}
	}

	return true;
}

//-----------------------------------------------------------------------------
void Device::print_help_message()
{
	os::printf(
	"Usage: crown [options]\n"
	"Options:\n\n"

	"All of the following options take precedence over\n"
	"environment variables and configuration files.\n\n"

	"  --help                Show this help.\n"
	"  --root-path <path>    Use <path> as the filesystem root path.\n"
	"  --user-path <path>    Use <path> as the filesystem user path.\n"
	"  --width <width>       Set the <width> of the render window.\n"
	"  --height <width>      Set the <height> of the render window.\n"
	"  --fullscreen          Start in fullscreen.\n"
	"  --gl                  Use OpenGL as rendering backend.\n"
	"  --gles                Use OpenGL|ES as rendering backend.\n"
	"  --dev                 Run the engine in development mode\n");
}

Device g_device;
Device* device()
{
	return &g_device;
}

} // namespace crown

<|endoftext|>


<commit_before>#include "headers\GameMechanics.h"

/*------------------------------ guitar ------------------------------*/

guitar::guitar(double value, std::string & name)
{
	this->price = this->value = value;
	this->brand = name;

	set_perceived_value(this->price / this->value);

 }

guitar::~guitar()
{
}

void guitar::set_perceived_value(double relation)
{
	if (relation <= 0.1 )
		purchasing_power = perceived_value::irresistible;
	else if (relation <= 1.5 && relation > 0.1 )
		purchasing_power = perceived_value::cheap;
	else if (relation <= 3 && relation > 1.5 )
		purchasing_power = perceived_value::neutral;
	else if (relation <= 5 && relation > 3 )
		purchasing_power = perceived_value::high;
	else if (relation <= 10 && relation > 5 )
		purchasing_power = perceived_value::overpriced;
	else if (relation > 10)
		purchasing_power = perceived_value::unattainable;
}

void guitar::set_price(double price)
{
	this->price = price;
	set_perceived_value(this->price / this->value);
}

/*------------------------------ employee ------------------------------*/

employee::employee(std::string & person, double value, int num) // 0 -low; 1- neutral 2-high
{
	this->name = person;
	salary = value;
	this->skill = efficiency(num);
}

employee::~employee()
{
}

/*------------------------------ store ------------------------------*/

store::store(user_profile * current, std::string & name, int num) //num 0 - poor; 1-middle; 2-rich
{
	this->user = current;
	this->name = name;
	this->setting = static_cast<area>(num);
	this->max_stock = 50 + 10 * setting; //can be altered, formula for max inventory
}

store::~store()
{
		//to work on
}

void store::buy_guitar(guitar * guitar)
{
	if (user->net_worth >= guitar->value) //buying from wholesale
	{
		user->net_worth -= guitar->value;
		this->inventory.push_back(guitar);
		return;
	}

	//else we need to deploy a message error (warning window)
}

void store::sell_algorithm()
{
	if (!inventory.empty()) //only when inventory is not empty
	{
		std::mt19937 random_numbers(rd()); //random number generator algorithm
		int position;

		for ( int i = buying_rate ; i != 0; i-- )
		{
			std::uniform_int_distribution<int> inventory_range(0, (inventory.size() - 1)); // random position to eliminate

			position = inventory_range(random_numbers); //position 0 -> size-1

			sell_instrument(position); // to be redefined upon piano class deployment

		}
	}

	//deploy message your inventory is empty. (else)
}

void store::sell_instrument(int position_offset)
{
	std::list<instrument *>::iterator it = inventory.begin();

	for ( ; position_offset != 0; position_offset--)  //proceding to position offset
	{
		it++;
	}

	// *it -> pointer to guitar
	user->net_worth += (*it)->price;
	this->reputation += ((*it)->value * 0.05); //5%of inventory's value added to store reputation

	delete (*it); //memory management

	inventory.erase(it);

}

<commit_msg>fixed game mechanics oversight<commit_after>#include "headers\GameMechanics.h"

/*------------------------------ guitar ------------------------------*/

guitar::guitar(double value, std::string & name)
{
	this->price = this->value = value;
	this->brand = name;

	set_perceived_value(this->price / this->value);

 }

guitar::~guitar()
{
}

void guitar::set_perceived_value(double relation)
{
	if (relation <= 0.1 )
		purchasing_power = perceived_value::irresistible;
	else if (relation <= 1.5 && relation > 0.1 )
		purchasing_power = perceived_value::cheap;
	else if (relation <= 3 && relation > 1.5 )
		purchasing_power = perceived_value::neutral;
	else if (relation <= 5 && relation > 3 )
		purchasing_power = perceived_value::high;
	else if (relation <= 10 && relation > 5 )
		purchasing_power = perceived_value::overpriced;
	else if (relation > 10)
		purchasing_power = perceived_value::unattainable;
}

void guitar::set_price(double price)
{
	this->price = price;
	set_perceived_value(this->price / this->value);
}

/*------------------------------ employee ------------------------------*/

employee::employee(std::string & person, double value, int num) // 0 -low; 1- neutral 2-high
{
	this->name = person;
	salary = value;
	this->skill = efficiency(num);
}

employee::~employee()
{
}

/*------------------------------ store ------------------------------*/

store::store(user_profile * current, std::string & name, int num) //num 0 - poor; 1-middle; 2-rich
{
	this->user = current;
	this->name = name;
	this->setting = static_cast<area>(num);
	this->max_stock = 50 + 10 * setting; //can be altered, formula for max inventory
}

store::~store()
{
		//to work on
}

void store::buy_guitar(guitar * guitar)
{
	if (user->net_worth >= guitar->value && inventory.size() < max_stock) //buying from wholesale
	{
		user->net_worth -= guitar->value;
		this->inventory.push_back(guitar);
		return;
	}

	//else we need to deploy a message error (warning window)
}

void store::sell_algorithm()
{
	if (!inventory.empty()) //only when inventory is not empty
	{
		std::mt19937 random_numbers(rd()); //random number generator algorithm
		int position;

		for ( int i = buying_rate ; i != 0; i-- )
		{
			std::uniform_int_distribution<int> inventory_range(0, (inventory.size() - 1)); // random position to eliminate

			position = inventory_range(random_numbers); //position 0 -> size-1

			sell_instrument(position); // to be redefined upon piano class deployment

		}
	}

	//deploy message your inventory is empty. (else)
}

void store::sell_instrument(int position_offset)
{
	std::list<instrument *>::iterator it = inventory.begin();

	for ( ; position_offset != 0; position_offset--)  //proceding to position offset
	{
		it++;
	}

	// *it -> pointer to guitar
	user->net_worth += (*it)->price;
	this->reputation += ((*it)->value * 0.05); //5%of inventory's value added to store reputation

	delete (*it); //memory management

	inventory.erase(it);

}

<|endoftext|>


<commit_before>//
// Simple wavefront .obj writer
//
#include "obj_writer.h"

static std::string GetFileBasename(const std::string& FileName)
{
    if(FileName.find_last_of(".") != std::string::npos)
        return FileName.substr(0, FileName.find_last_of("."));
    return "";
}

bool WriteMat(const std::string& filename, std::vector<tinyobj::shape_t> shapes) {
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
    return false;
  }

  std::map<std::string, tinyobj::material_t> mtl_table;

  for (size_t i = 0; i < shapes.size(); i++) {
    mtl_table[shapes[i].material.name] = shapes[i].material;
  }

  for (std::map<std::string, tinyobj::material_t>::iterator it = mtl_table.begin(); it != mtl_table.end(); it++) {

    tinyobj::material_t mat = it->second;

    fprintf(fp, "newmtl %s\n", mat.name.c_str());
    fprintf(fp, "Ka %f %f %f\n", mat.ambient[0], mat.ambient[1], mat.ambient[2]);
    fprintf(fp, "Kd %f %f %f\n", mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
    fprintf(fp, "Ks %f %f %f\n", mat.specular[0], mat.specular[1], mat.specular[2]);
    fprintf(fp, "Kt %f %f %f\n", mat.transmittance[0], mat.specular[1], mat.specular[2]);
    fprintf(fp, "Ke %f %f %f\n", mat.emission[0], mat.emission[1], mat.emission[2]);
    fprintf(fp, "Ns %f\n", mat.shininess);
    fprintf(fp, "Ni %f\n", mat.ior);
    // @todo { texture }
  }

  fclose(fp);

  return true;
}

bool WriteObj(const std::string& filename, std::vector<tinyobj::shape_t> shapes) {
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
    return false;
  }

  std::string basename = GetFileBasename(filename);
  std::string material_filename = basename + ".mtl";

  int v_offset = 0;
  int vn_offset = 0;
  int vt_offset = 0;

  fprintf(fp, "mtllib %s\n", material_filename.c_str());

  for (size_t i = 0; i < shapes.size(); i++) {

    bool has_vn = false;
    bool has_vt = false;

    if (shapes[i].name.empty()) {
      fprintf(fp, "g Unknown\n");
    } else {
      fprintf(fp, "g %s\n", shapes[i].name.c_str());
    }

    if (!shapes[i].material.name.empty()) {
      fprintf(fp, "usemtl %s\n", shapes[i].material.name.c_str());
    }

    // facevarying vtx
    for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
      for (int j = 0; j < 3; j++) {
        int idx = shapes[i].mesh.indices[3*k+j];
        fprintf(fp, "v %f %f %f\n",
          shapes[i].mesh.positions[3*idx+0],
          shapes[i].mesh.positions[3*idx+1],
          shapes[i].mesh.positions[3*idx+2]);
      }
    }

    // facevarying normal
    if (shapes[i].mesh.normals.size() > 0) {
      for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
        for (int j = 0; j < 3; j++) {
          int idx = shapes[i].mesh.indices[3*k+j];
          fprintf(fp, "vn %f %f %f\n",
            shapes[i].mesh.normals[3*idx+0],
            shapes[i].mesh.normals[3*idx+1],
            shapes[i].mesh.normals[3*idx+2]);
        }
      }
    }
    if (shapes[i].mesh.normals.size() > 0) has_vn = true;

    // texcoord
    if (shapes[i].mesh.texcoords.size() > 0) {
      for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
        for (int j = 0; j < 3; j++) {
          int idx = shapes[i].mesh.indices[3*k+j];
          fprintf(fp, "vt %f %f %f\n",
            shapes[i].mesh.texcoords[3*idx+0],
            shapes[i].mesh.texcoords[3*idx+1]);
        }
      }
    }
    if (shapes[i].mesh.texcoords.size() > 0) has_vt = true;

    // face
    for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {

      // Face index is 1-base.
      //int v0 = shapes[i].mesh.indices[3*k+0] + 1 + v_offset;
      //int v1 = shapes[i].mesh.indices[3*k+1] + 1 + v_offset;
      //int v2 = shapes[i].mesh.indices[3*k+2] + 1 + v_offset;
      int v0 = (3*k + 0) + 1 + v_offset;
      int v1 = (3*k + 1) + 1 + v_offset;
      int v2 = (3*k + 2) + 1 + v_offset;

      if (has_vn && has_vt) {
        fprintf(fp, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
          v0, v0, v0, v1, v1, v1, v2, v2, v2);
      } else if (has_vn && !has_vt) {
        fprintf(fp, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2);
      } else if (!has_vn && has_vt) {
        fprintf(fp, "f %d/%d %d/%d %d/%d\n", v0, v0, v1, v1, v2, v2);
      } else {
        fprintf(fp, "f %d %d %d\n", v0, v1, v2);
      }

    }

    v_offset  += shapes[i].mesh.indices.size();
    //vn_offset += shapes[i].mesh.normals.size() / 3;
    //vt_offset += shapes[i].mesh.texcoords.size() / 2;

  }

  fclose(fp);

  //
  // Write material file
  //
  bool ret = WriteMat(material_filename, shapes);

  return ret;
}

<commit_msg>Fix texcoord export.<commit_after>//
// Simple wavefront .obj writer
//
#include "obj_writer.h"

static std::string GetFileBasename(const std::string& FileName)
{
    if(FileName.find_last_of(".") != std::string::npos)
        return FileName.substr(0, FileName.find_last_of("."));
    return "";
}

bool WriteMat(const std::string& filename, std::vector<tinyobj::shape_t> shapes) {
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
    return false;
  }

  std::map<std::string, tinyobj::material_t> mtl_table;

  for (size_t i = 0; i < shapes.size(); i++) {
    mtl_table[shapes[i].material.name] = shapes[i].material;
  }

  for (std::map<std::string, tinyobj::material_t>::iterator it = mtl_table.begin(); it != mtl_table.end(); it++) {

    tinyobj::material_t mat = it->second;

    fprintf(fp, "newmtl %s\n", mat.name.c_str());
    fprintf(fp, "Ka %f %f %f\n", mat.ambient[0], mat.ambient[1], mat.ambient[2]);
    fprintf(fp, "Kd %f %f %f\n", mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
    fprintf(fp, "Ks %f %f %f\n", mat.specular[0], mat.specular[1], mat.specular[2]);
    fprintf(fp, "Kt %f %f %f\n", mat.transmittance[0], mat.specular[1], mat.specular[2]);
    fprintf(fp, "Ke %f %f %f\n", mat.emission[0], mat.emission[1], mat.emission[2]);
    fprintf(fp, "Ns %f\n", mat.shininess);
    fprintf(fp, "Ni %f\n", mat.ior);
    // @todo { texture }
  }

  fclose(fp);

  return true;
}

bool WriteObj(const std::string& filename, std::vector<tinyobj::shape_t> shapes) {
  FILE* fp = fopen(filename.c_str(), "w");
  if (!fp) {
    fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
    return false;
  }

  std::string basename = GetFileBasename(filename);
  std::string material_filename = basename + ".mtl";

  int v_offset = 0;
  int vn_offset = 0;
  int vt_offset = 0;

  fprintf(fp, "mtllib %s\n", material_filename.c_str());

  for (size_t i = 0; i < shapes.size(); i++) {

    bool has_vn = false;
    bool has_vt = false;

    if (shapes[i].name.empty()) {
      fprintf(fp, "g Unknown\n");
    } else {
      fprintf(fp, "g %s\n", shapes[i].name.c_str());
    }

    if (!shapes[i].material.name.empty()) {
      fprintf(fp, "usemtl %s\n", shapes[i].material.name.c_str());
    }

    // facevarying vtx
    for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
      for (int j = 0; j < 3; j++) {
        int idx = shapes[i].mesh.indices[3*k+j];
        fprintf(fp, "v %f %f %f\n",
          shapes[i].mesh.positions[3*idx+0],
          shapes[i].mesh.positions[3*idx+1],
          shapes[i].mesh.positions[3*idx+2]);
      }
    }

    // facevarying normal
    if (shapes[i].mesh.normals.size() > 0) {
      for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
        for (int j = 0; j < 3; j++) {
          int idx = shapes[i].mesh.indices[3*k+j];
          fprintf(fp, "vn %f %f %f\n",
            shapes[i].mesh.normals[3*idx+0],
            shapes[i].mesh.normals[3*idx+1],
            shapes[i].mesh.normals[3*idx+2]);
        }
      }
    }
    if (shapes[i].mesh.normals.size() > 0) has_vn = true;

    // facevarying texcoord
    if (shapes[i].mesh.texcoords.size() > 0) {
      for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
        for (int j = 0; j < 3; j++) {
          int idx = shapes[i].mesh.indices[3*k+j];
          fprintf(fp, "vt %f %f %f\n",
            shapes[i].mesh.texcoords[2*idx+0],
            shapes[i].mesh.texcoords[2*idx+1]);
        }
      }
    }
    if (shapes[i].mesh.texcoords.size() > 0) has_vt = true;

    // face
    for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {

      // Face index is 1-base.
      //int v0 = shapes[i].mesh.indices[3*k+0] + 1 + v_offset;
      //int v1 = shapes[i].mesh.indices[3*k+1] + 1 + v_offset;
      //int v2 = shapes[i].mesh.indices[3*k+2] + 1 + v_offset;
      int v0 = (3*k + 0) + 1 + v_offset;
      int v1 = (3*k + 1) + 1 + v_offset;
      int v2 = (3*k + 2) + 1 + v_offset;

      if (has_vn && has_vt) {
        fprintf(fp, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
          v0, v0, v0, v1, v1, v1, v2, v2, v2);
      } else if (has_vn && !has_vt) {
        fprintf(fp, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2);
      } else if (!has_vn && has_vt) {
        fprintf(fp, "f %d/%d %d/%d %d/%d\n", v0, v0, v1, v1, v2, v2);
      } else {
        fprintf(fp, "f %d %d %d\n", v0, v1, v2);
      }

    }

    v_offset  += shapes[i].mesh.indices.size();
    //vn_offset += shapes[i].mesh.normals.size() / 3;
    //vt_offset += shapes[i].mesh.texcoords.size() / 2;

  }

  fclose(fp);

  //
  // Write material file
  //
  bool ret = WriteMat(material_filename, shapes);

  return ret;
}

<|endoftext|>


<commit_before>// [!output PROJECT_NAME].cpp : main source file for [!output PROJECT_NAME].exe
//

#include "stdafx.h"

#include "resource.h"

#include "TasksView.h"
#include "AboutDlg.h"
#include "TasksFrame.h"

#include <shellapi.h>

#include <memory>

CAppModule _Module;

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CTasksFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}

	wndMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

	AddFontResourceEx(L"FontAwesome.otf", FR_PRIVATE, nullptr);

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	int nRet = Run(lpstrCmdLine, nCmdShow);

	_Module.Term();

	RemoveFontResourceEx(L"FontAwesome.otf", FR_PRIVATE, nullptr);
	::CoUninitialize();

	return nRet;
}
<commit_msg>Switching from "just FontAwesome" to any font available<commit_after>// [!output PROJECT_NAME].cpp : main source file for [!output PROJECT_NAME].exe
//

#include "stdafx.h"

#include "resource.h"

#include "TasksView.h"
#include "AboutDlg.h"
#include "TasksFrame.h"

#include <shellapi.h>

#include <memory>
#include <net/filesystem.hpp>

namespace fs = filesystem;

fs::path exe_dir() {
	static fs::path dir = fs::app_directory();
	return dir;
}

CAppModule _Module;

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
	CMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	CTasksFrame wndMain;

	if(wndMain.CreateEx() == NULL)
	{
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}

	wndMain.ShowWindow(nCmdShow);

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

class Fonts {
	std::vector<fs::path> m_fonts;
public:
	Fonts()
	{
		for (auto entry : fs::dir(exe_dir() / "fonts"))
		{
			if (entry.status().is_directory())
				continue;
			auto count = AddFontResourceEx(entry.path().wnative().c_str(), FR_PRIVATE, nullptr);
			if (count)
				m_fonts.push_back(entry.path());
		}
	}

	~Fonts()
	{
		for (auto& path : m_fonts)
			RemoveFontResourceExW(path.wnative().c_str(), FR_PRIVATE, nullptr);
	}
};

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
	HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to
// make the EXE free threaded. This means that calls come in on a random RPC thread.
//	HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	ATLASSERT(SUCCEEDED(hRes));

	Fonts external;

	// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
	::DefWindowProc(NULL, 0, 0, 0L);

	AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);	// add flags to support other controls

	hRes = _Module.Init(NULL, hInstance);
	ATLASSERT(SUCCEEDED(hRes));

	int nRet = Run(lpstrCmdLine, nCmdShow);

	_Module.Term();

	::CoUninitialize();

	return nRet;
}
<|endoftext|>


<commit_before>//===-- Definition of Win32 wrapper functions -----------------------------===//
//
// Copyright (c) 2013 Philip Jackson
// This file may be freely distributed under the MIT license.
//
//===----------------------------------------------------------------------===//

#include "util.h"

#include "curt.h"
#include "error.h"
#include "include_windows.h"

#include <limits>

using std::string;
using std::wstring;

extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace curt {

HINSTANCE thisModule() {
  return reinterpret_cast<HINSTANCE>(&__ImageBase);
}

string wideToUtf8(wstring wide) {
  if (wide.empty())
    return {};

  if (wide.size() > std::numeric_limits<int>::max())
    throw std::runtime_error("String too long to convert to UTF-8");

  const auto nChar = static_cast<int>(wide.size());
#if (WINVER >= 0x0600)
  const auto flags = WC_ERR_INVALID_CHARS;
#else
  const auto flags = 0;
#endif

  const auto nBytes = wideCharToMultiByte(CP_UTF8, flags, wide.data(), nChar, nullptr, 0, nullptr, nullptr);

  auto narrow = string(nBytes, '\0');
  wideCharToMultiByte(CP_UTF8, flags, wide.data(), nChar, &narrow[0], nBytes, nullptr, nullptr);

  return narrow;
}

wstring utf8ToWide(string utf8) {
  if (utf8.empty())
    return {};

  if (utf8.size() > std::numeric_limits<int>::max())
    throw std::runtime_error("String too long to convert to wide chars");

  const auto nBytes = static_cast<int>(utf8.size());
  const auto flags = MB_ERR_INVALID_CHARS;

  const auto nChar = multiByteToWideChar(CP_UTF8, flags, utf8.data(), nBytes, nullptr, 0);

  auto wide = std::wstring(nChar, '\0');
  multiByteToWideChar(CP_UTF8, flags, utf8.data(), nBytes, &wide[0], nChar);

  return wide;
}

wstring loadStringW(unsigned int resId) {
  wchar_t* buff;
  auto asCharPtr = reinterpret_cast<wchar_t*>(&buff);
  auto len = curt::loadString(thisModule(), resId, asCharPtr, 0);
  return wstring(buff, len);
}

string loadString(unsigned int resId) {
  return wideToUtf8(loadStringW(resId));
}

WPARAM pumpMessages() {
  MSG msg;
  while (getMessage(&msg, nullptr, 0, 0)) {
    translateMessage(&msg);
    dispatchMessage(&msg);

    throwIfSavedException();
  }

  return msg.wParam;
}

WPARAM pumpMessages(HandleOr<HWND> translateWnd, HACCEL accelTable) {
  MSG msg;
  while (getMessage(&msg, nullptr, 0, 0)) {
    if (!translateAccelerator(translateWnd, accelTable, &msg)) {
      translateMessage(&msg);
      dispatchMessage(&msg);

      throwIfSavedException();
    }
  }

  return msg.wParam;
}

static LRESULT CALLBACK ctrlBgProc(
  HWND wnd,
  UINT msg,
  WPARAM w,
  LPARAM l,
  UINT_PTR,
  DWORD_PTR color
) {
  try {
    switch (msg) {
      case WM_CTLCOLORBTN:
      case WM_CTLCOLORSTATIC:
      {
        auto hdc = reinterpret_cast<HDC>(w);
        setDCBrushColor(hdc, static_cast<unsigned long>(color));
        return reinterpret_cast<LRESULT>(getStockObject(DC_BRUSH));
      }
      default:
        return defSubclassProc(wnd, msg, w, l);
    }
  }
  catch (...) {
    saveCurrentException();
    return 0;
  }
}

void subclassControlBackground(HandleOr<HWND> wnd, unsigned long rgb) {
  setWindowSubclass(wnd, ctrlBgProc, 0, rgb);
}

static LRESULT CALLBACK appViewProc(
  HWND wnd,
  UINT msg,
  WPARAM w,
  LPARAM l,
  UINT_PTR,
  DWORD_PTR
) {
  try {
    if (msg == WM_DESTROY)
      PostQuitMessage(0);

    return defSubclassProc(wnd, msg, w, l);
  }
  catch (...) {
    saveCurrentException();
    return 0;
  }
}

void subclassAppView(HandleOr<HWND> wnd) {
  setWindowSubclass(wnd, appViewProc, 0, 0);
}

Font defaultFont() {
  auto metrics = NONCLIENTMETRICSW{ sizeof(NONCLIENTMETRICSW) };
  systemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
  return createFontIndirect(&metrics.lfMessageFont);
}

void setControlToDefaultFont(HandleOr<HWND> parent, int id) {
  static auto font = defaultFont();
  auto asWParam = reinterpret_cast<WPARAM>(font.get());
  curt::sendDlgItemMessage(parent, id, WM_SETFONT, asWParam, 1);
}

static HWND createCtrl(
  LPCWSTR className,
  unsigned long style,
  HWND parent,
  int id
) {
  auto x = CW_USEDEFAULT; // All dimensions are default
  auto menuOrId = reinterpret_cast<HMENU>(id);
  auto control = curt::createWindowEx(
    0,
    className,
    nullptr,
    WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | style,
    x, x, x, x,
    parent,
    menuOrId,
    curt::thisModule(),
    nullptr
  );

  return control.release();
}

HWND createStatic(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"STATIC", styles, parent, id);
}

HWND createButton(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"BUTTON", BS_PUSHBUTTON | styles, parent, id);
}

HWND createEdit(HandleOr<HWND> parent, int id, unsigned long styles) {
  const auto editStyles = ES_LEFT | ES_AUTOHSCROLL | WS_BORDER;
  return createCtrl(L"EDIT", editStyles | styles, parent, id);
}

HWND createCheckbox(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"BUTTON", BS_AUTOCHECKBOX | styles, parent, id);
}

} // end namespace curt
<commit_msg>Fixed warnings in the 32-bit build.<commit_after>//===-- Definition of Win32 wrapper functions -----------------------------===//
//
// Copyright (c) 2013 Philip Jackson
// This file may be freely distributed under the MIT license.
//
//===----------------------------------------------------------------------===//

#include "util.h"

#include "curt.h"
#include "error.h"
#include "include_windows.h"

#include <limits>

using std::string;
using std::wstring;

extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace curt {

HINSTANCE thisModule() {
  return reinterpret_cast<HINSTANCE>(&__ImageBase);
}

string wideToUtf8(wstring wide) {
  if (wide.empty())
    return {};

  const auto maxSize = std::numeric_limits<int>::max();
  if (wide.size() > static_cast<wstring::size_type>(maxSize))
    throw std::runtime_error("String too long to convert to UTF-8");

  const auto nChar = static_cast<int>(wide.size());
#if (WINVER >= 0x0600)
  const auto flags = WC_ERR_INVALID_CHARS;
#else
  const auto flags = 0;
#endif

  const auto nBytes = wideCharToMultiByte(CP_UTF8, flags, wide.data(), nChar, nullptr, 0, nullptr, nullptr);

  auto narrow = string(nBytes, '\0');
  wideCharToMultiByte(CP_UTF8, flags, wide.data(), nChar, &narrow[0], nBytes, nullptr, nullptr);

  return narrow;
}

wstring utf8ToWide(string utf8) {
  if (utf8.empty())
    return {};

  const auto maxSize = std::numeric_limits<int>::max();
  if (utf8.size() > static_cast<string::size_type>(maxSize))
    throw std::runtime_error("String too long to convert to wide chars");

  const auto nBytes = static_cast<int>(utf8.size());
  const auto flags = MB_ERR_INVALID_CHARS;

  const auto nChar = multiByteToWideChar(CP_UTF8, flags, utf8.data(), nBytes, nullptr, 0);

  auto wide = std::wstring(nChar, '\0');
  multiByteToWideChar(CP_UTF8, flags, utf8.data(), nBytes, &wide[0], nChar);

  return wide;
}

wstring loadStringW(unsigned int resId) {
  wchar_t* buff;
  auto asCharPtr = reinterpret_cast<wchar_t*>(&buff);
  auto len = curt::loadString(thisModule(), resId, asCharPtr, 0);
  return wstring(buff, len);
}

string loadString(unsigned int resId) {
  return wideToUtf8(loadStringW(resId));
}

WPARAM pumpMessages() {
  MSG msg;
  while (getMessage(&msg, nullptr, 0, 0)) {
    translateMessage(&msg);
    dispatchMessage(&msg);

    throwIfSavedException();
  }

  return msg.wParam;
}

WPARAM pumpMessages(HandleOr<HWND> translateWnd, HACCEL accelTable) {
  MSG msg;
  while (getMessage(&msg, nullptr, 0, 0)) {
    if (!translateAccelerator(translateWnd, accelTable, &msg)) {
      translateMessage(&msg);
      dispatchMessage(&msg);

      throwIfSavedException();
    }
  }

  return msg.wParam;
}

static LRESULT CALLBACK ctrlBgProc(
  HWND wnd,
  UINT msg,
  WPARAM w,
  LPARAM l,
  UINT_PTR,
  DWORD_PTR color
) {
  try {
    switch (msg) {
      case WM_CTLCOLORBTN:
      case WM_CTLCOLORSTATIC:
      {
        auto hdc = reinterpret_cast<HDC>(w);
        setDCBrushColor(hdc, static_cast<unsigned long>(color));
        return reinterpret_cast<LRESULT>(getStockObject(DC_BRUSH));
      }
      default:
        return defSubclassProc(wnd, msg, w, l);
    }
  }
  catch (...) {
    saveCurrentException();
    return 0;
  }
}

void subclassControlBackground(HandleOr<HWND> wnd, unsigned long rgb) {
  setWindowSubclass(wnd, ctrlBgProc, 0, rgb);
}

static LRESULT CALLBACK appViewProc(
  HWND wnd,
  UINT msg,
  WPARAM w,
  LPARAM l,
  UINT_PTR,
  DWORD_PTR
) {
  try {
    if (msg == WM_DESTROY)
      PostQuitMessage(0);

    return defSubclassProc(wnd, msg, w, l);
  }
  catch (...) {
    saveCurrentException();
    return 0;
  }
}

void subclassAppView(HandleOr<HWND> wnd) {
  setWindowSubclass(wnd, appViewProc, 0, 0);
}

Font defaultFont() {
  auto metrics = NONCLIENTMETRICSW{ sizeof(NONCLIENTMETRICSW) };
  systemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
  return createFontIndirect(&metrics.lfMessageFont);
}

void setControlToDefaultFont(HandleOr<HWND> parent, int id) {
  static auto font = defaultFont();
  auto asWParam = reinterpret_cast<WPARAM>(font.get());
  curt::sendDlgItemMessage(parent, id, WM_SETFONT, asWParam, 1);
}

static HWND createCtrl(
  LPCWSTR className,
  unsigned long style,
  HWND parent,
  int id
) {
  auto x = CW_USEDEFAULT; // All dimensions are default
  auto menuOrId = reinterpret_cast<HMENU>(id);
  auto control = curt::createWindowEx(
    0,
    className,
    nullptr,
    WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | style,
    x, x, x, x,
    parent,
    menuOrId,
    curt::thisModule(),
    nullptr
  );

  return control.release();
}

HWND createStatic(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"STATIC", styles, parent, id);
}

HWND createButton(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"BUTTON", BS_PUSHBUTTON | styles, parent, id);
}

HWND createEdit(HandleOr<HWND> parent, int id, unsigned long styles) {
  const auto editStyles = ES_LEFT | ES_AUTOHSCROLL | WS_BORDER;
  return createCtrl(L"EDIT", editStyles | styles, parent, id);
}

HWND createCheckbox(HandleOr<HWND> parent, int id, unsigned long styles) {
  return createCtrl(L"BUTTON", BS_AUTOCHECKBOX | styles, parent, id);
}

} // end namespace curt
<|endoftext|>