<commit_before>//
//  GvmClusterMain.cpp
//  GvmCpp
//
//  Created by Mo DeJong on 8/14/15.
//
// 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
//

#include <iostream>

#include <unordered_map>

#import "Gvm.hpp"

using namespace std;
using namespace Gvm;

// Load points from a file

template<typename V, typename P>
vector<V> loadPointsFromBGR(string filename)
{
  vector<V> allPoints;

  FILE *fp = fopen(filename.c_str(), "rb");

  fseek(fp, 0, SEEK_END);

  int numBytes = (int) ftell(fp);

  if (numBytes == 0) {
    cerr << "empty input YUV file contains zero BGRA pixels" << endl;
    exit(1);
  }

  if ((numBytes % sizeof(uint32_t)) != 0) {
    cerr << "input YUV must be a file with a whole number of BGRA pixels" << endl;
    exit(1);
  }

  fseek(fp, 0, SEEK_SET);

  // In DEBUG mode, use unordered_map to check for duplicate pixels in the input

#if defined(DEBUG)
  unordered_map<uint32_t, uint32_t> uniquePixelMap;
#endif // DEBUG

  for (; numBytes > 0 ; numBytes -= 4) {
    uint32_t pixel;

    int numRead = (int)fread(&pixel, sizeof(pixel), 1, fp);
    if (numRead != 1) {
      cerr << "could not read whole pixel from YUV input at offset " << ftell(fp) << endl;
      exit(1);
    }

    uint32_t B = pixel & 0xFF;
    uint32_t G = (pixel >> 8) & 0xFF;
    uint32_t R = (pixel >> 16) & 0xFF;

#if defined(DEBUG)
    uint32_t pixelNoAlpha = (R << 16) | (G << 8) | B;

    if (uniquePixelMap.count(pixelNoAlpha) > 0) {
      cerr << "input contains duplicate BGR pixel" << endl;
      exit(1);
    }
#endif // DEBUG

    P x = B;
    P y = G;
    P z = R;

    V coordsVec;

    coordsVec[0] = x;
    coordsVec[1] = y;
    coordsVec[2] = z;

    allPoints.push_back(coordsVec);
  }

  fclose(fp);

  return allPoints;
}

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

  string filename = "/Users/modejong/Development/ImageCompression/GVMCluster/Lenna_int_order.yuv";

  // Using float instead of double cuts memory usage down just a bit, like 10%

  typedef double FP;
//  typedef float FP;

  // ClusterVector and ClusterVspace define the low level fixed size
  // vector of values that represents the point values.

  typedef GvmStdVector<FP,3> ClusterVector;
  typedef GvmVectorSpace<ClusterVector,FP,3> ClusterVectorSpace;

  // A "key" is a vector of points in one specific cluster.

  typedef vector<ClusterVector> ClusterKey;

  vector<ClusterVector> allPoints = loadPointsFromBGR<ClusterVector,FP>(filename);

  cout << "read " << allPoints.size() << " pixels from " << filename << endl;

  ClusterVectorSpace vspace;

  const int numClusters = 2048;
  //const int numClusters = 1024;
  //const int numClusters = 512; // 30 megs of ram, 8 sec CPU
  //const int numClusters = 256; // 16 megs of ram, 3 sec of CPU
  //const int numClusters = 128; // 16 megs of ram, 1 sec of CPU

  GvmClusters<ClusterVectorSpace, ClusterVector, ClusterKey, FP> clusters(vspace, numClusters);

  GvmListKeyer<ClusterVectorSpace, ClusterVector, ClusterKey, FP> listKeyer;

  // Install key combiner for list of points, caller must manage ptr lifetime

  clusters.setKeyer(&listKeyer);

  // Insert each point into clusters. Each point is
  // associated with a list of points called a "key".
  // This key object lifetime must be managed by the caller
  // for performance reasons.

  vector<ClusterKey> allKeys;
  allKeys.reserve(allPoints.size());

  for ( ClusterVector & pt : allPoints ) {
    // Key is a list of (list of points)
    if (false) {
    assert(pt.getDimensions() == 3);
    cout << "clustering point (B G R) (" << pt[0] << " " << pt[1] << " " << pt[2] << ")" << endl;
    }

    allKeys.push_back(ClusterKey ());
    ClusterKey *key = &allKeys[allKeys.size() - 1];
    key->push_back(pt);

    clusters.add(1, pt, key);
  }

  cout << "generated " << clusters.clusters.size() << " clusters" << endl;

  // Emit clustered results as YUV data padded out to 256 with zeros

  // vector<GvmResult>

  int clusteri = 0;

  vector<GvmResult<ClusterVectorSpace, ClusterVector, ClusterKey, FP>> results = clusters.results();

  for ( auto & result : results ) {
    cout << "cluster[" << clusteri << "]: " << result.toString() << endl;
    clusteri++;
  }

  // Write clustered pixels as YUV output

  int totalPixelsWritten = 0;

  string outYuvFilename = "out.yuv";

  FILE *outFP = fopen(outYuvFilename.c_str(), "wb");

  for (int i = 0; i < results.size(); i++) {
    int clusterID = i; // keep to byte range

    ClusterKey *allKeys = results[i].getKey();

    cout << "cluster " << clusterID << " contains " << allKeys->size() << " pixels" << endl;

    int pixelsWritten = 0;

    for ( ClusterVector &pt : *allKeys ) {
      FP x = pt[0];
      FP y = pt[1];
      FP z = pt[2];

      if (x < 0 || x > 255) {
        assert(0);
      }
      if (y < 0 || y > 255) {
        assert(0);
      }
      if (z < 0 || z > 255) {
        assert(0);
      }

      uint32_t B = int(x);
      uint32_t G = int(y);
      uint32_t R = int(z);

      uint32_t pixel = (0xFF << 24) | (R << 16) | (G << 8) | B;

      int numWritten = (int)fwrite(&pixel, sizeof(uint32_t), 1, outFP);
      assert(numWritten == 1);
      pixelsWritten++;
    }

    totalPixelsWritten += pixelsWritten;

    if (true) {
      // Pad each cluster out to 256

      int numPointsInCluster = pixelsWritten;

      int over = numPointsInCluster % 256;
      int under = 0;

      if (over == 0) {
        // Cluster of exactly 256 pixels, emit 256 zeros to indicate this case.
        under = 256;
      } else {
        under = 256 - over;
      }

      for (int j = 0; j < under; j++) {
        uint32_t pixel = 0;
        int numWritten = (int)fwrite(&pixel, sizeof(uint32_t), 1, outFP);
        assert(numWritten == 1);
        totalPixelsWritten++;
      }
    }
  }

  fclose(outFP);

  cout << "wrote " << totalPixelsWritten << " total pixels to " << outYuvFilename << endl;

  int totalRowsOf256 = totalPixelsWritten/256;
  if ((totalPixelsWritten % 256) != 0) {
    assert(0);
  }

  cout << "wrote 256 x " << totalRowsOf256 << endl;

  cout << "as " << results.size() << " number of clusters" << endl;

  // In the combination phase, pixels split into clusters are combined based on calculation
  // of distances from one cluster center to the next.

  return 0;
}
<commit_msg>enable 256 clusters configuration<commit_after>//
//  GvmClusterMain.cpp
//  GvmCpp
//
//  Created by Mo DeJong on 8/14/15.
//
// 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
//

#include <iostream>

#include <unordered_map>

#import "Gvm.hpp"

using namespace std;
using namespace Gvm;

// Load points from a file

template<typename V, typename P>
vector<V> loadPointsFromBGR(string filename)
{
  vector<V> allPoints;

  FILE *fp = fopen(filename.c_str(), "rb");

  fseek(fp, 0, SEEK_END);

  int numBytes = (int) ftell(fp);

  if (numBytes == 0) {
    cerr << "empty input YUV file contains zero BGRA pixels" << endl;
    exit(1);
  }

  if ((numBytes % sizeof(uint32_t)) != 0) {
    cerr << "input YUV must be a file with a whole number of BGRA pixels" << endl;
    exit(1);
  }

  fseek(fp, 0, SEEK_SET);

  // In DEBUG mode, use unordered_map to check for duplicate pixels in the input

#if defined(DEBUG)
  unordered_map<uint32_t, uint32_t> uniquePixelMap;
#endif // DEBUG

  for (; numBytes > 0 ; numBytes -= 4) {
    uint32_t pixel;

    int numRead = (int)fread(&pixel, sizeof(pixel), 1, fp);
    if (numRead != 1) {
      cerr << "could not read whole pixel from YUV input at offset " << ftell(fp) << endl;
      exit(1);
    }

    uint32_t B = pixel & 0xFF;
    uint32_t G = (pixel >> 8) & 0xFF;
    uint32_t R = (pixel >> 16) & 0xFF;

#if defined(DEBUG)
    uint32_t pixelNoAlpha = (R << 16) | (G << 8) | B;

    if (uniquePixelMap.count(pixelNoAlpha) > 0) {
      cerr << "input contains duplicate BGR pixel" << endl;
      exit(1);
    }
#endif // DEBUG

    P x = B;
    P y = G;
    P z = R;

    V coordsVec;

    coordsVec[0] = x;
    coordsVec[1] = y;
    coordsVec[2] = z;

    allPoints.push_back(coordsVec);
  }

  fclose(fp);

  return allPoints;
}

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

  string filename = "/Users/modejong/Development/ImageCompression/GVMCluster/Lenna_int_order.yuv";

  // Using float instead of double cuts memory usage down just a bit, like 10%

  typedef double FP;
//  typedef float FP;

  // ClusterVector and ClusterVspace define the low level fixed size
  // vector of values that represents the point values.

  typedef GvmStdVector<FP,3> ClusterVector;
  typedef GvmVectorSpace<ClusterVector,FP,3> ClusterVectorSpace;

  // A "key" is a vector of points in one specific cluster.

  typedef vector<ClusterVector> ClusterKey;

  vector<ClusterVector> allPoints = loadPointsFromBGR<ClusterVector,FP>(filename);

  cout << "read " << allPoints.size() << " pixels from " << filename << endl;

  ClusterVectorSpace vspace;

  //const int numClusters = 2048;
  //const int numClusters = 1024;
  //const int numClusters = 512; // 30 megs of ram, 8 sec CPU
  const int numClusters = 256; // 16 megs of ram, 3 sec of CPU
  //const int numClusters = 128; // 16 megs of ram, 1 sec of CPU

  GvmClusters<ClusterVectorSpace, ClusterVector, ClusterKey, FP> clusters(vspace, numClusters);

  GvmListKeyer<ClusterVectorSpace, ClusterVector, ClusterKey, FP> listKeyer;

  // Install key combiner for list of points, caller must manage ptr lifetime

  clusters.setKeyer(&listKeyer);

  // Insert each point into clusters. Each point is
  // associated with a list of points called a "key".
  // This key object lifetime must be managed by the caller
  // for performance reasons.

  vector<ClusterKey> allKeys;
  allKeys.reserve(allPoints.size());

  for ( ClusterVector & pt : allPoints ) {
    // Key is a list of (list of points)
    if (false) {
    assert(pt.getDimensions() == 3);
    cout << "clustering point (B G R) (" << pt[0] << " " << pt[1] << " " << pt[2] << ")" << endl;
    }

    allKeys.push_back(ClusterKey ());
    ClusterKey *key = &allKeys[allKeys.size() - 1];
    key->push_back(pt);

    clusters.add(1, pt, key);
  }

  cout << "generated " << clusters.clusters.size() << " clusters" << endl;

  // Emit clustered results as YUV data padded out to 256 with zeros

  // vector<GvmResult>

  int clusteri = 0;

  vector<GvmResult<ClusterVectorSpace, ClusterVector, ClusterKey, FP>> results = clusters.results();

  for ( auto & result : results ) {
    cout << "cluster[" << clusteri << "]: " << result.toString() << endl;
    clusteri++;
  }

  // Write clustered pixels as YUV output

  int totalPixelsWritten = 0;

  string outYuvFilename = "out.yuv";

  FILE *outFP = fopen(outYuvFilename.c_str(), "wb");

  for (int i = 0; i < results.size(); i++) {
    int clusterID = i; // keep to byte range

    ClusterKey *allKeys = results[i].getKey();

    cout << "cluster " << clusterID << " contains " << allKeys->size() << " pixels" << endl;

    int pixelsWritten = 0;

    for ( ClusterVector &pt : *allKeys ) {
      FP x = pt[0];
      FP y = pt[1];
      FP z = pt[2];

      if (x < 0 || x > 255) {
        assert(0);
      }
      if (y < 0 || y > 255) {
        assert(0);
      }
      if (z < 0 || z > 255) {
        assert(0);
      }

      uint32_t B = int(x);
      uint32_t G = int(y);
      uint32_t R = int(z);

      uint32_t pixel = (0xFF << 24) | (R << 16) | (G << 8) | B;

      int numWritten = (int)fwrite(&pixel, sizeof(uint32_t), 1, outFP);
      assert(numWritten == 1);
      pixelsWritten++;
    }

    totalPixelsWritten += pixelsWritten;

    if (true) {
      // Pad each cluster out to 256

      int numPointsInCluster = pixelsWritten;

      int over = numPointsInCluster % 256;
      int under = 0;

      if (over == 0) {
        // Cluster of exactly 256 pixels, emit 256 zeros to indicate this case.
        under = 256;
      } else {
        under = 256 - over;
      }

      for (int j = 0; j < under; j++) {
        uint32_t pixel = 0;
        int numWritten = (int)fwrite(&pixel, sizeof(uint32_t), 1, outFP);
        assert(numWritten == 1);
        totalPixelsWritten++;
      }
    }
  }

  fclose(outFP);

  cout << "wrote " << totalPixelsWritten << " total pixels to " << outYuvFilename << endl;

  int totalRowsOf256 = totalPixelsWritten/256;
  if ((totalPixelsWritten % 256) != 0) {
    assert(0);
  }

  cout << "wrote 256 x " << totalRowsOf256 << endl;

  cout << "as " << results.size() << " number of clusters" << endl;

  // In the combination phase, pixels split into clusters are combined based on calculation
  // of distances from one cluster center to the next.

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Menu creation and other helper functions.
 * By 2MB Solutions (https://2mb.solutions)
 * Provided under the MIT license. See license.txt for details.
 * Billy: https://stormdragon.tk
 * Michael: https://michaeltaboada.me
*/
#include <dynamic_menu.h>
#include <string>
#include <vector>
#include <misc.h>
#include <soundplayer.h>
using std::string;
using std::vector;

dynamic_menu* create_menu(vector<string> items, vector<string> sounditems, vector<int(*)(dynamic_menu*, int, void*)> vec = vector<int(*)(dynamic_menu*, int, void*)>(), vector<void*> vec2 = vector<void*>()) {
unsigned int soundnumber = sounditems.size();
unsigned int numberofitems = items.size();
dynamic_menu* menu = new dynamic_menu((numberofitems > soundnumber)?numberofitems:soundnumber);
for(unsigned int x = 1; x <= numberofitems; x++) {
if(items[x-1] != "") {
menu->add_item_text(items[x-1], x, ((vec.size() >= x)?vec[x-1]:NULL), ((vec2.size() >= x)?vec2[x-1]:NULL));
}
}
for(unsigned int y = 1; y <= soundnumber; y++) {
if(sounditems[y-1] != "") {
menu->add_item_sound(sounditems[y-1], y, ((vec.size() >= y)?vec[y-1]:NULL), ((vec2.size() >= y)?vec2[y-1]:NULL));
}
}
return menu;
}

vector<string>* get_dir_children(string dir, int dir_or_file) {
ALLEGRO_FS_ENTRY *f = al_create_fs_entry((((string)(al_path_cstr(al_get_standard_path(ALLEGRO_RESOURCES_PATH), ALLEGRO_NATIVE_PATH_SEP)))+dir).c_str());
if(!f) {
return NULL;
}
if(al_open_directory(f)) {
vector<string>* vec = new vector<string>();
ALLEGRO_FS_ENTRY *fs = al_read_directory(f);
while(fs) {
const char* fn = al_get_fs_entry_name(fs);
string fsn = "";
int x;
for(x = (int)(strlen(fn)-1); x >= 0; x--) {
if(fn[x] == '/' || fn[x] == '\\') {
break;
}
}
for(unsigned int y = x+1; y < strlen(fn); y++) {
fsn += fn[y];
}
if(dir_or_file == 0) {
vec->push_back(fsn);
}
else if(dir_or_file == 1 && (al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISFILE) == ALLEGRO_FILEMODE_ISFILE) {
vec->push_back(fsn);
}
else if(dir_or_file == 2 && (al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISDIR) == ALLEGRO_FILEMODE_ISDIR){
vec->push_back(fsn);
}
if(fs) {
al_destroy_fs_entry(fs);
}
fs = al_read_directory(f);
}
al_close_directory(f);
al_destroy_fs_entry(f);
return vec;
}
else {
al_destroy_fs_entry(f);
return NULL;
}
}

string generic_menu(vector<string> extra_items, string music = "", bool learn_sounds_yes = true) {
sound menu_music;
if(music != "") {
menu_music.load(music);
menu_music.set_loop(true);
menu_music.play();
}
	vector<string> real_items;
real_items.push_back("Play game");
real_items.push_back("View instructions");
if (learn_sounds_yes) {
real_items.push_back("Learn game sounds.");
}
for (unsigned int x = 0; x < extra_items.size(); x++) {
real_items.push_back(extra_items[x]);
}
real_items.push_back("view credits");
real_items.push_back("Exit game");
dynamic_menu* menu = create_menu(real_items, vector<string>());
if (menu) {
int pos = -1;
do {
	pos = menu->run_extended("", "Use your arrow keys to navigate the menu, and enter to select.", 1, true);
if(pos == 1) {
if(music != "")
fade(&menu_music);
delete menu;
return "play";
}
else if(pos == (int)(real_items.size()-1)) {
credits();
}
else if(pos == 2) {
instructions();
}
else if(pos == 3 && learn_sounds_yes) {
if(music != "")
fade(&menu_music);
learn_sounds();
if(music != "") {
menu_music.set_gain(0);
menu_music.play();
}
}
else if (pos == (int)(real_items.size())) {
if(music != "")
fade(&menu_music);
delete menu;
return "exit";
}
else if(pos == 0) {
fade(&menu_music);
delete menu;
return "escape";
}
else if(pos == -1) {
fade(&menu_music);
delete menu;
return "invalid";
}
else {
if(music != "")
fade(&menu_music);
delete menu;
return extra_items[pos-(real_items.size()-3)];
}
}
while (pos != -1 && pos != 0 && pos != (int)(real_items.size()));
}
if(music != "")
menu_music.stop();
return "invalid";
}

<commit_msg>updated the menu creation function to exclude credits or instructions if not available<commit_after>/*
 * Menu creation and other helper functions.
 * By 2MB Solutions (https://2mb.solutions)
 * Provided under the MIT license. See license.txt for details.
 * Billy: https://stormdragon.tk
 * Michael: https://michaeltaboada.me
*/
#include <dynamic_menu.h>
#include <string>
#include <vector>
#include <misc.h>
#include <soundplayer.h>
using std::string;
using std::vector;

dynamic_menu* create_menu(vector<string> items, vector<string> sounditems, vector<int(*)(dynamic_menu*, int, void*)> vec = vector<int(*)(dynamic_menu*, int, void*)>(), vector<void*> vec2 = vector<void*>()) {
unsigned int soundnumber = sounditems.size();
unsigned int numberofitems = items.size();
dynamic_menu* menu = new dynamic_menu((numberofitems > soundnumber)?numberofitems:soundnumber);
for(unsigned int x = 1; x <= numberofitems; x++) {
if(items[x-1] != "") {
menu->add_item_text(items[x-1], x, ((vec.size() >= x)?vec[x-1]:NULL), ((vec2.size() >= x)?vec2[x-1]:NULL));
}
}
for(unsigned int y = 1; y <= soundnumber; y++) {
if(sounditems[y-1] != "") {
menu->add_item_sound(sounditems[y-1], y, ((vec.size() >= y)?vec[y-1]:NULL), ((vec2.size() >= y)?vec2[y-1]:NULL));
}
}
return menu;
}

vector<string>* get_dir_children(string dir, int dir_or_file) {
ALLEGRO_FS_ENTRY *f = al_create_fs_entry((((string)(al_path_cstr(al_get_standard_path(ALLEGRO_RESOURCES_PATH), ALLEGRO_NATIVE_PATH_SEP)))+dir).c_str());
if(!f) {
return NULL;
}
if(al_open_directory(f)) {
vector<string>* vec = new vector<string>();
ALLEGRO_FS_ENTRY *fs = al_read_directory(f);
while(fs) {
const char* fn = al_get_fs_entry_name(fs);
string fsn = "";
int x;
for(x = (int)(strlen(fn)-1); x >= 0; x--) {
if(fn[x] == '/' || fn[x] == '\\') {
break;
}
}
for(unsigned int y = x+1; y < strlen(fn); y++) {
fsn += fn[y];
}
if(dir_or_file == 0) {
vec->push_back(fsn);
}
else if(dir_or_file == 1 && (al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISFILE) == ALLEGRO_FILEMODE_ISFILE) {
vec->push_back(fsn);
}
else if(dir_or_file == 2 && (al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISDIR) == ALLEGRO_FILEMODE_ISDIR){
vec->push_back(fsn);
}
if(fs) {
al_destroy_fs_entry(fs);
}
fs = al_read_directory(f);
}
al_close_directory(f);
al_destroy_fs_entry(f);
return vec;
}
else {
al_destroy_fs_entry(f);
return NULL;
}
}

string generic_menu(vector<string> extra_items, string music = "", bool learn_sounds_yes = true) {
bool instructions,credits;
sound menu_music;
if(music != "") {
menu_music.load(music);
menu_music.set_loop(true);
menu_music.play();
}
	vector<string> real_items;
real_items.push_back("Play game");
string path = al_path_cstr(al_get_standard_path(ALLEGRO_RESOURCES_PATH), ALLEGRO_NATIVE_PATH_SEP);
path = path+(string)("manual.txt");
        FILE* f = fopen(path.c_str(), "r");
        if(f) {
real_items.push_back("View instructions");
instructions = true;
fclose(f);
        }
else {
instructions = false;
}
if (learn_sounds_yes) {
real_items.push_back("Learn game sounds.");
}
for (unsigned int x = 0; x < extra_items.size(); x++) {
real_items.push_back(extra_items[x]);
}
path = al_path_cstr(al_get_standard_path(ALLEGRO_RESOURCES_PATH), ALLEGRO_NATIVE_PATH_SEP);
path = path+(string)("credits.txt");
        FILE* f = fopen(path.c_str(), "r");
        if(f) {
real_items.push_back("view credits");
credits = true;
fclose(f);
        }
else {
credits = false;
}
real_items.push_back("Exit game");
dynamic_menu* menu = create_menu(real_items, vector<string>());
if (menu) {
int pos = -1;
do {
	pos = menu->run_extended("", "Use your arrow keys to navigate the menu, and enter to select.", 1, true);
if(pos == 1) {
if(music != "")
fade(&menu_music);
delete menu;
return "play";
}
else if(pos == (int)(real_items.size()-1) && credits == true) {
credits();
}
else if(pos == 2 && instructions == true) {
instructions();
}
else if (learn_sounds_yes && ((pos == 3 && instructions == true) || (pos == 2 && instructions == false))) {
if(music != "")
fade(&menu_music);
learn_sounds();
if(music != "") {
menu_music.set_gain(0);
menu_music.play();
}
}
else if (pos == (int)(real_items.size())) {
if(music != "")
fade(&menu_music);
delete menu;
return "exit";
}
else if(pos == 0) {
fade(&menu_music);
delete menu;
return "escape";
}
else if(pos == -1) {
fade(&menu_music);
delete menu;
return "invalid";
}
else {
if(music != "")
fade(&menu_music);
delete menu;
if (instructions == true && learn_sounds_yes == true) {
return extra_items[pos-(real_items.size()-3)];
}
else if(instructions == true || learn_sounds_yes == true) {
return extra_items[pos-(real_items.size()-2)];
}
else {
return extra_items[pos-(real_items.size()-1)];
}
}
while (pos != -1 && pos != 0 && pos != (int)(real_items.size()));
}
if(music != "")
menu_music.stop();
return "invalid";
}

<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "SrwDecoder.h"
#include "TiffParserOlympus.h"
#if defined(__unix__) || defined(__APPLE__)
#include <stdlib.h>
#endif
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

SrwDecoder::SrwDecoder(TiffIFD *rootIFD, FileMap* file):
    RawDecoder(file), mRootIFD(rootIFD) {
}

SrwDecoder::~SrwDecoder(void) {
  if (mRootIFD)
    delete mRootIFD;
  mRootIFD = NULL;
}

RawImage SrwDecoder::decodeRawInternal() {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  if (data.empty())
    ThrowRDE("Srw Decoder: No image data found");

  TiffIFD* raw = data[0];

  int compression = raw->getEntry(COMPRESSION)->getInt();
  if (32769 != compression && 32770 != compression )
    ThrowRDE("Srw Decoder: Unsupported compression");

  if (32769 == compression)
  {
    this->decodeUncompressed(raw, false);
    return mRaw;
  }

  if (32770 == compression)
  {
    this->decodeUncompressed(raw, true);
    return mRaw;
  }
  ThrowRDE("Srw Decoder: Unsupported compression");
  return mRaw;
}

void SrwDecoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("Srw Support check: Model name found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}

void SrwDecoder::decodeMetaData(CameraMetaData *meta) {
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("SRW Meta Decoder: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  data = mRootIFD->getIFDsWithTag(CFAPATTERN);
  if (!this->checkCameraSupported(meta, make, model, "") && !data.empty() && data[0]->hasEntry(CFAREPEATPATTERNDIM)) {
    const unsigned short* pDim = data[0]->getEntry(CFAREPEATPATTERNDIM)->getShortArray();
    iPoint2D cfaSize(pDim[1], pDim[0]);
    if (cfaSize.x != 2 && cfaSize.y != 2)
      ThrowRDE("SRW Decoder: Unsupported CFA pattern size");

    const uchar8* cPat = data[0]->getEntry(CFAPATTERN)->getData();
    if (cfaSize.area() != data[0]->getEntry(CFAPATTERN)->count)
      ThrowRDE("SRW Decoder: CFA pattern dimension and pattern count does not match: %d.");

    for (int y = 0; y < cfaSize.y; y++) {
      for (int x = 0; x < cfaSize.x; x++) {
        uint32 c1 = cPat[x+y*cfaSize.x];
        CFAColor c2;
        switch (c1) {
            case 0:
              c2 = CFA_RED; break;
            case 1:
              c2 = CFA_GREEN; break;
            case 2:
              c2 = CFA_BLUE; break;
            default:
              c2 = CFA_UNKNOWN;
              ThrowRDE("SRW Decoder: Unsupported CFA Color.");
        }
        mRaw->cfa.setColorAt(iPoint2D(x, y), c2);
      }
    }
    printf("Camera CFA: %s\n", mRaw->cfa.asString().c_str());
  }

  int iso = 0;
  if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
    iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();

  setMetaData(meta, make, model, "", iso);
}

} // namespace RawSpeed
<commit_msg>Attempt to guess byteorder on Samsung NX-200.<commit_after>#include "StdAfx.h"
#include "SrwDecoder.h"
#include "TiffParserOlympus.h"
#if defined(__unix__) || defined(__APPLE__)
#include <stdlib.h>
#endif
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

SrwDecoder::SrwDecoder(TiffIFD *rootIFD, FileMap* file):
RawDecoder(file), mRootIFD(rootIFD) {
  decoderVersion = 1;
}

SrwDecoder::~SrwDecoder(void) {
  if (mRootIFD)
    delete mRootIFD;
  mRootIFD = NULL;
}

RawImage SrwDecoder::decodeRawInternal() {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  if (data.empty())
    ThrowRDE("Srw Decoder: No image data found");

  TiffIFD* raw = data[0];

  int compression = raw->getEntry(COMPRESSION)->getInt();
  int bits = raw->getEntry(BITSPERSAMPLE)->getInt();

  if (32769 != compression && 32770 != compression )
    ThrowRDE("Srw Decoder: Unsupported compression");

  if (32769 == compression)
  {
    this->decodeUncompressed(raw, false);
    return mRaw;
  }

  if (32770 == compression)
  {
    this->decodeUncompressed(raw, bits == 12);
    return mRaw;
  }
  ThrowRDE("Srw Decoder: Unsupported compression");
  return mRaw;
}

void SrwDecoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("Srw Support check: Model name found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}

void SrwDecoder::decodeMetaData(CameraMetaData *meta) {
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("SRW Meta Decoder: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  data = mRootIFD->getIFDsWithTag(CFAPATTERN);
  if (!this->checkCameraSupported(meta, make, model, "") && !data.empty() && data[0]->hasEntry(CFAREPEATPATTERNDIM)) {
    const unsigned short* pDim = data[0]->getEntry(CFAREPEATPATTERNDIM)->getShortArray();
    iPoint2D cfaSize(pDim[1], pDim[0]);
    if (cfaSize.x != 2 && cfaSize.y != 2)
      ThrowRDE("SRW Decoder: Unsupported CFA pattern size");

    const uchar8* cPat = data[0]->getEntry(CFAPATTERN)->getData();
    if (cfaSize.area() != data[0]->getEntry(CFAPATTERN)->count)
      ThrowRDE("SRW Decoder: CFA pattern dimension and pattern count does not match: %d.");

    for (int y = 0; y < cfaSize.y; y++) {
      for (int x = 0; x < cfaSize.x; x++) {
        uint32 c1 = cPat[x+y*cfaSize.x];
        CFAColor c2;
        switch (c1) {
            case 0:
              c2 = CFA_RED; break;
            case 1:
              c2 = CFA_GREEN; break;
            case 2:
              c2 = CFA_BLUE; break;
            default:
              c2 = CFA_UNKNOWN;
              ThrowRDE("SRW Decoder: Unsupported CFA Color.");
        }
        mRaw->cfa.setColorAt(iPoint2D(x, y), c2);
      }
    }
    printf("Camera CFA: %s\n", mRaw->cfa.asString().c_str());
  }

  int iso = 0;
  if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
    iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();

  setMetaData(meta, make, model, "", iso);
}

} // namespace RawSpeed
<|endoftext|>


<commit_before>/*
 * crtlink.h
 *
 *  Created on: 27.06.2013
 *      Author: andreas
 */

#ifndef CRTLINK_H_
#define CRTLINK_H_ 1

#include <exception>
#include <algorithm>
#include <ostream>
#include <string>
#include <map>
#include <set>

#include <rofl/common/caddress.h>
#include <rofl/common/logging.h>
#include <rofl/common/cmemory.h>

#include <netlink/object.h>
#include <netlink/route/link.h>
#include <inttypes.h>
#include <linux/if_arp.h>

#include <roflibs/netlink/crtaddrs.hpp>
#include <roflibs/netlink/crtneighs.hpp>

namespace rofcore {

class crtlink {
public:

	class eRtLinkBase		: public std::runtime_error {
	public:
		eRtLinkBase(const std::string& __arg) : std::runtime_error(__arg) {};
	};
	class eRtLinkNotFound	: public eRtLinkBase {
	public:
		eRtLinkNotFound(const std::string& __arg) : eRtLinkBase(__arg) {};
	};
	class eRtLinkExists		: public eRtLinkBase {
	public:
		eRtLinkExists(const std::string& __arg) : eRtLinkBase(__arg) {};
	};

public:

	/**
	 *
	 */
	crtlink() :
		flags(0),
		af(0),
		arptype(0),
		ifindex(0),
		mtu(0),
		master(0) {};

	/**
	 *
	 */
	crtlink(struct rtnl_link *link) :
		flags(0),
		af(0),
		arptype(0),
		ifindex(0),
		mtu(0),
		master(0)
	{
		char s_buf[128];
		memset(s_buf, 0, sizeof(s_buf));

		nl_object_get((struct nl_object*)link); // increment reference counter by one

		devname.assign(rtnl_link_get_name(link));
		maddr 	= rofl::cmacaddr(nl_addr2str(rtnl_link_get_addr(link), 		s_buf, sizeof(s_buf)));
		bcast 	= rofl::cmacaddr(nl_addr2str(rtnl_link_get_broadcast(link), s_buf, sizeof(s_buf)));
		flags 	= rtnl_link_get_flags(link);
		af 		= rtnl_link_get_family(link);
		arptype = rtnl_link_get_arptype(link);
		ifindex	= rtnl_link_get_ifindex(link);
		mtu 	= rtnl_link_get_mtu(link);
		master = rtnl_link_get_master(link);

		nl_object_put((struct nl_object*)link); // decrement reference counter by one
	};

	/**
	 *
	 */
	virtual
	~crtlink() {};

	/**
	 *
	 */
	crtlink(const crtlink& rtlink) { *this = rtlink; };

	/**
	 *
	 */
	crtlink&
	operator= (const crtlink& rtlink) {
		if (this == &rtlink)
			return *this;

		devname = rtlink.devname;
		maddr	= rtlink.maddr;
		bcast	= rtlink.bcast;
		flags	= rtlink.flags;
		af		= rtlink.af;
		arptype	= rtlink.arptype;
		ifindex	= rtlink.ifindex;
		mtu		= rtlink.mtu;
		master	= rtlink.master;

//		addrs_in4	= rtlink.addrs_in4;
//		addrs_in6	= rtlink.addrs_in6;
//		neighs_ll	= rtlink.neighs_ll;
//		neighs_in4	= rtlink.neighs_in4;
//		neighs_in6	= rtlink.neighs_in6;

		return *this;
	};

	/**
	 *
	 */
	bool
	operator== (const crtlink& rtlink) {
		return ((devname == rtlink.devname) && (ifindex == rtlink.ifindex) && (maddr == rtlink.maddr));
	}

#if 0
public:

	/**
	 *
	 */
	const crtaddrs_in4&
	get_addrs_in4() const { return addrs_in4; };

	/**
	 *
	 */
	crtaddrs_in4&
	set_addrs_in4() { return addrs_in4; };

	/**
	 *
	 */
	const crtaddrs_in6&
	get_addrs_in6() const { return addrs_in6; };

	/**
	 *
	 */
	crtaddrs_in6&
	set_addrs_in6() { return addrs_in6; };

	/**
	 *
	 */
	const crtneighs_ll&
	get_neighs_ll() const { return neighs_ll; };

	/**
	 *
	 */
	crtneighs_ll&
	set_neighs_ll() { return neighs_ll; };

	/**
	 *
	 */
	const crtneighs_in4&
	get_neighs_in4() const { return neighs_in4; };

	/**
	 *
	 */
	crtneighs_in4&
	set_neighs_in4() { return neighs_in4; };

	/**
	 *
	 */
	const crtneighs_in6&
	get_neighs_in6() const { return neighs_in6; };

	/**
	 *
	 */
	crtneighs_in6&
	set_neighs_in6() { return neighs_in6; };
#endif

public:

	/**
	 *
	 */
	const std::string&
	get_devname() const { return devname; };

	/**
	 *
	 */
	const rofl::cmacaddr&
	get_hwaddr() const { return maddr; };

	/**
	 *
	 */
	const rofl::cmacaddr&
	get_broadcast() const { return bcast; };

	/**
	 *
	 */
	unsigned int
	get_flags() const { return flags; };

	/**
	 *
	 */
	int
	get_family() const { return af; };

	/**
	 *
	 */
	unsigned int
	get_arptype() const { return arptype; };

	/**
	 *
	 */
	int
	get_ifindex() const { return ifindex; };

	/**
	 *
	 */
	unsigned int
	get_mtu() const { return mtu; };

	int
	get_master() const { return master; }

public:

	/**
	 *
	 */
	friend std::ostream&
	operator<< (std::ostream& os, crtlink const& rtlink) {
		os << rofcore::indent(0) << "<crtlink: >" << std::endl;
		os << rofcore::indent(2) << "<devname: " << rtlink.devname 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<hwaddr: >" << std::endl;
		os << rofcore::indent(4) << rtlink.maddr;
		os << rofcore::indent(2) << "<bcast: >" << std::endl;
		os << rofcore::indent(4) << rtlink.bcast;
		os << rofcore::indent(2) << "<flags: " << (std::hex) << rtlink.flags << (std::dec) << " >" << std::endl;
		os << rofcore::indent(2) << "<af: " << rtlink.af 				<< " >" << std::endl;
		os << rofcore::indent(2) << "<arptype: " << rtlink.arptype 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<ifindex: " << rtlink.ifindex 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<mtu: " << rtlink.mtu 			<< " >" << std::endl;
		os << rofcore::indent(2) << "<master: " << rtlink.master	<< " >" << std::endl;

//		{ rofcore::indent i(2); os << rtlink.addrs_in4; };
//		{ rofcore::indent i(2); os << rtlink.addrs_in6; };
//		{ rofcore::indent i(2); os << rtlink.neighs_ll; };
//		{ rofcore::indent i(2); os << rtlink.neighs_in4; };
//		{ rofcore::indent i(2); os << rtlink.neighs_in6; };

		return os;
	};

	/**
	 *
	 */
	std::string
	str() const {
		/*
		 * 2: mgt0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
         *	   link/ether 52:54:00:b5:b4:e2 brd ff:ff:ff:ff:ff:ff
		 */
		std::stringstream ss;
		ss << "@" << ifindex << ": " << devname << ": <";
		// flags
		if (flags & IFF_UP) 		ss << "UP,";
		if (flags & IFF_BROADCAST) 	ss << "BROADCAST,";
		if (flags & IFF_POINTOPOINT) ss << "POINTOPOINT,";
		if (flags & IFF_RUNNING) 	ss << "RUNNING,";
		if (flags & IFF_NOARP) 		ss << "NOARP,";
		if (flags & IFF_PROMISC) 	ss << "PROMISC,";
		if (flags & IFF_MASTER) 	ss << "MASTER,";
		if (flags & IFF_SLAVE) 		ss << "SLAVE,";
		if (flags & IFF_MULTICAST) 	ss << "MULTICAST,";
		if (flags & IFF_LOWER_UP) 	ss << "LOWER_UP,";
		ss << "> mtu: " << mtu << std::endl;
		ss << "link/";
		if (arptype == ARPHRD_ETHER)
			ss << "ether ";
		else
			ss << "unknown ";
		ss << maddr.str() << " brd " << bcast.str() << std::endl;
//		if (not addrs_in4.empty())  ss << addrs_in4.str();
//		if (not addrs_in6.empty())  ss << addrs_in6.str();
//		if (not neighs_ll.empty())  ss << neighs_ll.str();
//		if (not neighs_in4.empty()) ss << neighs_in4.str();
//		if (not neighs_in6.empty()) ss << neighs_in6.str();
		return ss.str();
	};

	/**
	 *
	 */
	class crtlink_find_by_ifindex : public std::unary_function<crtlink,bool> {
		unsigned int ifindex;
	public:
		crtlink_find_by_ifindex(unsigned int ifindex) :
			ifindex(ifindex) {};
		bool operator() (crtlink const& rtl) {
			return (ifindex == rtl.ifindex);
		};
		bool operator() (std::pair<unsigned int, crtlink> const& p) {
			return (ifindex == p.second.ifindex);
		};
		bool operator() (std::pair<unsigned int, crtlink*> const& p) {
			return (ifindex == p.second->ifindex);
		};
	};

	/**
	 *
	 */
	class crtlink_find_by_devname : public std::unary_function<crtlink,bool> {
		std::string devname;
	public:
		crtlink_find_by_devname(std::string const& devname) :
			devname(devname) {};
		bool operator() (crtlink const& rtl) {
			return (devname == rtl.devname);
		};
		bool operator() (std::pair<unsigned int, crtlink> const& p) {
			return (devname == p.second.devname);
		};
#if 0
		bool operator() (std::pair<unsigned int, crtlink*> const& p) {
			return (devname == p.second->devname);
		};
#endif
	};

private:

	std::string				devname;	// device name (e.g. eth0)
	rofl::cmacaddr			maddr;		// mac address
	rofl::cmacaddr			bcast; 		// broadcast address
	unsigned int			flags;		// link flags
	int						af;			// address family (AF_INET, AF_UNSPEC, ...)
	unsigned int			arptype;	// ARP type (e.g. ARPHDR_ETHER)
	int						ifindex;	// interface index
	unsigned int			mtu;		// maximum transfer unit
	int						master;		// ifindex of master interface

//	crtaddrs_in4			addrs_in4;
//	crtaddrs_in6			addrs_in6;
//	crtneighs_ll			neighs_ll;
//	crtneighs_in4			neighs_in4;
//	crtneighs_in6			neighs_in6;

};

}; // end of namespace dptmap

#endif /* CRTLINK_H_ */
<commit_msg>read bridge vlans via libnl<commit_after>/*
 * crtlink.h
 *
 *  Created on: 27.06.2013
 *      Author: andreas
 */

#ifndef CRTLINK_H_
#define CRTLINK_H_ 1

#include <exception>
#include <algorithm>
#include <ostream>
#include <string>
#include <map>
#include <set>

#include <rofl/common/caddress.h>
#include <rofl/common/logging.h>
#include <rofl/common/cmemory.h>

#include <netlink/object.h>
#include <netlink/route/link.h>
#include <netlink/route/link/bridge.h>
#include <inttypes.h>
#include <linux/if_arp.h>

#include <roflibs/netlink/crtaddrs.hpp>
#include <roflibs/netlink/crtneighs.hpp>

namespace rofcore {

class crtlink {
public:

	class eRtLinkBase		: public std::runtime_error {
	public:
		eRtLinkBase(const std::string& __arg) : std::runtime_error(__arg) {};
	};
	class eRtLinkNotFound	: public eRtLinkBase {
	public:
		eRtLinkNotFound(const std::string& __arg) : eRtLinkBase(__arg) {};
	};
	class eRtLinkExists		: public eRtLinkBase {
	public:
		eRtLinkExists(const std::string& __arg) : eRtLinkBase(__arg) {};
	};

public:

	/**
	 *
	 */
	crtlink() :
		flags(0),
		af(0),
		arptype(0),
		ifindex(0),
		mtu(0),
		master(0) {};

	/**
	 *
	 */
	crtlink(struct rtnl_link *link) :
		flags(0),
		af(0),
		arptype(0),
		ifindex(0),
		mtu(0),
		master(0)
	{
		char s_buf[128];
		memset(s_buf, 0, sizeof(s_buf));

		nl_object_get((struct nl_object*)link); // increment reference counter by one

		devname.assign(rtnl_link_get_name(link));
		maddr 	= rofl::cmacaddr(nl_addr2str(rtnl_link_get_addr(link), 		s_buf, sizeof(s_buf)));
		bcast 	= rofl::cmacaddr(nl_addr2str(rtnl_link_get_broadcast(link), s_buf, sizeof(s_buf)));
		flags 	= rtnl_link_get_flags(link);
		af 		= rtnl_link_get_family(link);
		arptype = rtnl_link_get_arptype(link);
		ifindex	= rtnl_link_get_ifindex(link);
		mtu 	= rtnl_link_get_mtu(link);
		master = rtnl_link_get_master(link);

		if (AF_BRIDGE == af) {
			struct rtnl_link_bridge_vlan *vlans = rtnl_link_bridge_get_port_vlan(link);
			memcpy(&this->br_vlan, vlans, sizeof(struct rtnl_link_bridge_vlan));
		}

		nl_object_put((struct nl_object*)link); // decrement reference counter by one
	};

	/**
	 *
	 */
	virtual
	~crtlink() {};

	/**
	 *
	 */
	crtlink(const crtlink& rtlink) { *this = rtlink; };

	/**
	 *
	 */
	crtlink&
	operator= (const crtlink& rtlink) {
		if (this == &rtlink)
			return *this;

		devname = rtlink.devname;
		maddr	= rtlink.maddr;
		bcast	= rtlink.bcast;
		flags	= rtlink.flags;
		af		= rtlink.af;
		arptype	= rtlink.arptype;
		ifindex	= rtlink.ifindex;
		mtu		= rtlink.mtu;
		master	= rtlink.master;

//		addrs_in4	= rtlink.addrs_in4;
//		addrs_in6	= rtlink.addrs_in6;
//		neighs_ll	= rtlink.neighs_ll;
//		neighs_in4	= rtlink.neighs_in4;
//		neighs_in6	= rtlink.neighs_in6;

		return *this;
	};

	/**
	 *
	 */
	bool
	operator== (const crtlink& rtlink) {
		return ((devname == rtlink.devname) && (ifindex == rtlink.ifindex) && (maddr == rtlink.maddr));
	}

#if 0
public:

	/**
	 *
	 */
	const crtaddrs_in4&
	get_addrs_in4() const { return addrs_in4; };

	/**
	 *
	 */
	crtaddrs_in4&
	set_addrs_in4() { return addrs_in4; };

	/**
	 *
	 */
	const crtaddrs_in6&
	get_addrs_in6() const { return addrs_in6; };

	/**
	 *
	 */
	crtaddrs_in6&
	set_addrs_in6() { return addrs_in6; };

	/**
	 *
	 */
	const crtneighs_ll&
	get_neighs_ll() const { return neighs_ll; };

	/**
	 *
	 */
	crtneighs_ll&
	set_neighs_ll() { return neighs_ll; };

	/**
	 *
	 */
	const crtneighs_in4&
	get_neighs_in4() const { return neighs_in4; };

	/**
	 *
	 */
	crtneighs_in4&
	set_neighs_in4() { return neighs_in4; };

	/**
	 *
	 */
	const crtneighs_in6&
	get_neighs_in6() const { return neighs_in6; };

	/**
	 *
	 */
	crtneighs_in6&
	set_neighs_in6() { return neighs_in6; };
#endif

public:

	/**
	 *
	 */
	const std::string&
	get_devname() const { return devname; };

	/**
	 *
	 */
	const rofl::cmacaddr&
	get_hwaddr() const { return maddr; };

	/**
	 *
	 */
	const rofl::cmacaddr&
	get_broadcast() const { return bcast; };

	/**
	 *
	 */
	unsigned int
	get_flags() const { return flags; };

	/**
	 *
	 */
	int
	get_family() const { return af; };

	/**
	 *
	 */
	unsigned int
	get_arptype() const { return arptype; };

	/**
	 *
	 */
	int
	get_ifindex() const { return ifindex; };

	/**
	 *
	 */
	unsigned int
	get_mtu() const { return mtu; };

	int
	get_master() const { return master; }

public:

	/**
	 *
	 */
	friend std::ostream&
	operator<< (std::ostream& os, crtlink const& rtlink) {
		os << rofcore::indent(0) << "<crtlink: >" << std::endl;
		os << rofcore::indent(2) << "<devname: " << rtlink.devname 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<hwaddr: >" << std::endl;
		os << rofcore::indent(4) << rtlink.maddr;
		os << rofcore::indent(2) << "<bcast: >" << std::endl;
		os << rofcore::indent(4) << rtlink.bcast;
		os << rofcore::indent(2) << "<flags: " << (std::hex) << rtlink.flags << (std::dec) << " >" << std::endl;
		os << rofcore::indent(2) << "<af: " << rtlink.af 				<< " >" << std::endl;
		os << rofcore::indent(2) << "<arptype: " << rtlink.arptype 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<ifindex: " << rtlink.ifindex 	<< " >" << std::endl;
		os << rofcore::indent(2) << "<mtu: " << rtlink.mtu 			<< " >" << std::endl;
		os << rofcore::indent(2) << "<master: " << rtlink.master	<< " >" << std::endl;

//		{ rofcore::indent i(2); os << rtlink.addrs_in4; };
//		{ rofcore::indent i(2); os << rtlink.addrs_in6; };
//		{ rofcore::indent i(2); os << rtlink.neighs_ll; };
//		{ rofcore::indent i(2); os << rtlink.neighs_in4; };
//		{ rofcore::indent i(2); os << rtlink.neighs_in6; };

		return os;
	};

	/**
	 *
	 */
	std::string
	str() const {
		/*
		 * 2: mgt0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
         *	   link/ether 52:54:00:b5:b4:e2 brd ff:ff:ff:ff:ff:ff
		 */
		std::stringstream ss;
		ss << "@" << ifindex << ": " << devname << ": <";
		// flags
		if (flags & IFF_UP) 		ss << "UP,";
		if (flags & IFF_BROADCAST) 	ss << "BROADCAST,";
		if (flags & IFF_POINTOPOINT) ss << "POINTOPOINT,";
		if (flags & IFF_RUNNING) 	ss << "RUNNING,";
		if (flags & IFF_NOARP) 		ss << "NOARP,";
		if (flags & IFF_PROMISC) 	ss << "PROMISC,";
		if (flags & IFF_MASTER) 	ss << "MASTER,";
		if (flags & IFF_SLAVE) 		ss << "SLAVE,";
		if (flags & IFF_MULTICAST) 	ss << "MULTICAST,";
		if (flags & IFF_LOWER_UP) 	ss << "LOWER_UP,";
		ss << "> mtu: " << mtu << std::endl;
		ss << "link/";
		if (arptype == ARPHRD_ETHER)
			ss << "ether ";
		else
			ss << "unknown ";
		ss << maddr.str() << " brd " << bcast.str() << std::endl;
//		if (not addrs_in4.empty())  ss << addrs_in4.str();
//		if (not addrs_in6.empty())  ss << addrs_in6.str();
//		if (not neighs_ll.empty())  ss << neighs_ll.str();
//		if (not neighs_in4.empty()) ss << neighs_in4.str();
//		if (not neighs_in6.empty()) ss << neighs_in6.str();
		return ss.str();
	};

	/**
	 *
	 */
	class crtlink_find_by_ifindex : public std::unary_function<crtlink,bool> {
		unsigned int ifindex;
	public:
		crtlink_find_by_ifindex(unsigned int ifindex) :
			ifindex(ifindex) {};
		bool operator() (crtlink const& rtl) {
			return (ifindex == rtl.ifindex);
		};
		bool operator() (std::pair<unsigned int, crtlink> const& p) {
			return (ifindex == p.second.ifindex);
		};
		bool operator() (std::pair<unsigned int, crtlink*> const& p) {
			return (ifindex == p.second->ifindex);
		};
	};

	/**
	 *
	 */
	class crtlink_find_by_devname : public std::unary_function<crtlink,bool> {
		std::string devname;
	public:
		crtlink_find_by_devname(std::string const& devname) :
			devname(devname) {};
		bool operator() (crtlink const& rtl) {
			return (devname == rtl.devname);
		};
		bool operator() (std::pair<unsigned int, crtlink> const& p) {
			return (devname == p.second.devname);
		};
#if 0
		bool operator() (std::pair<unsigned int, crtlink*> const& p) {
			return (devname == p.second->devname);
		};
#endif
	};

private:

	std::string				devname;	// device name (e.g. eth0)
	rofl::cmacaddr			maddr;		// mac address
	rofl::cmacaddr			bcast; 		// broadcast address
	unsigned int			flags;		// link flags
	int						af;			// address family (AF_INET, AF_UNSPEC, ...)
	unsigned int			arptype;	// ARP type (e.g. ARPHDR_ETHER)
	int						ifindex;	// interface index
	unsigned int			mtu;		// maximum transfer unit
	int						master;		// ifindex of master interface

	struct rtnl_link_bridge_vlan	br_vlan;
//	crtaddrs_in4			addrs_in4;
//	crtaddrs_in6			addrs_in6;
//	crtneighs_ll			neighs_ll;
//	crtneighs_in4			neighs_in4;
//	crtneighs_in6			neighs_in6;

};

}; // end of namespace dptmap

#endif /* CRTLINK_H_ */
<|endoftext|>


<commit_before>//*******************************************************************
// Copyright (C) 2000 ImageLinks Inc.
//
// License:  See top level LICENSE.txt file.
//
// Author: Ken Melero
//         Originally written by Oscar Kramer.
//
// Description:  This app displays a binary file in a nice
//               formatted view.  Very helpful for finding offsets of
//               binary headers.
//
//********************************************************************
// $Id: ossim-btoa.cpp 22209 2013-03-29 13:38:38Z dburken $

#include <ossim/base/ossimArgumentParser.h>
#include <ossim/base/ossimEbcdicToAscii.h>

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

// Regular print with offset, hex, and ascii section.
static void print( FILE* fptr, bool isEbcdic )
{
   int           offset = 0;
   unsigned char bin_data[16];
   char          asc_data[17];
   int           hex_data[16];
   int           nbytes;
   int           i;

   asc_data[16] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, 16, 1, fptr);
      for(i=0; i<16; i++)
      {
         hex_data[i] = (int) bin_data[i];

         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf("%06d  %02X %02X %02X %02X %02X %02X %02X %02X  "
             "%02X %02X %02X %02X %02X %02X %02X %02X  %16s\n", offset,
             hex_data[0],  hex_data[1],  hex_data[2],  hex_data[3],
             hex_data[4],  hex_data[5],  hex_data[6],  hex_data[7],
             hex_data[8],  hex_data[9],  hex_data[10], hex_data[11],
             hex_data[12], hex_data[13], hex_data[14], hex_data[15],
             asc_data);

      offset += 16;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // End: print(...)

// Wide print offset and ascii section only.
static void printWide( FILE* fptr, bool isEbcdic )
{
   const int WIDTH = 64;

   int           offset = 0;
   unsigned char bin_data[WIDTH];
   char          asc_data[WIDTH+1];
   int           nbytes;
   int           i = 0;

   asc_data[WIDTH] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, WIDTH, 1, fptr);
      for( i = 0; i < WIDTH; ++i )
      {
         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf("%06d  %64s\n", offset, asc_data);

      offset += WIDTH;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // End printWide( ... )

// Wide print ascii section only.
static void printAscii( FILE* fptr, bool isEbcdic )
{
   const int WIDTH = 80;

   int           offset = 0;
   unsigned char bin_data[WIDTH];
   char          asc_data[WIDTH+1];
   int           nbytes;
   int           i = 0;

   asc_data[WIDTH] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, WIDTH, 1, fptr);
      for( i = 0; i < WIDTH; ++i )
      {
         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf( "%80s\n", asc_data );

      offset += WIDTH;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // printAscii

int main(int argc, char** argv)
{
   // Parse the args:
   ossimArgumentParser argumentParser(&argc, argv);

   enum PrintMode
   {
      ALL   = 0, // offsets hex ascii - default
      WIDE  = 1, // offsets ascii     - "-w" option
      ASCII = 2  // ascii             - "-a" option
   };

   // Check for options:
   bool isEbcdic = false;
   PrintMode mode = ALL;

   if ( argumentParser.read("-e") )
   {
      isEbcdic = true;
   }
   if ( argumentParser.read("-w") )
   {
      mode = WIDE;
   }
   if ( argumentParser.read("-a") )
   {
      if ( mode != ALL )
      {
         std::cerr << "Cannot use -a and -w options." << std::endl;
         return -1;
      }
      mode = ASCII;
   }

   if ( argumentParser.read("-h") || argumentParser.read("--help") ||
        (argumentParser.argc() != 2) )
   {
      std::cout << "\nBinary to ascii usage: btoa [options] <binary_file>\n"
                << "Options:\n"
                << "-e Indicates text characters are ebcdic and should be"
                << " converted to ascii.\n"
                << "-h or --help usage\n"
                << "-a Ascii mode, prints 64 characters wide with no offset or hex data.\n"
                << "-w Wide mode, prints offset and 64 characters wide with no hex data.\n"
                << "Notes:\n"
                << "  1) Non-ascii characters are printed as dot in ascii output.\n"
                << "  2) Default mode prints offsets, hex and ascii data."
                << std::endl;
      return 0;
   }

   FILE* fptr = fopen(argv[argumentParser.argc()-1], "rb");
   if (fptr == 0)
   {
      std::cout << "\nError opening file " << argv[argumentParser.argc()-1]
                << std::endl << std::endl;
      return -1;
   }

   if ( mode == WIDE )
   {
      printWide( fptr, isEbcdic );
   }
   else if ( mode == ASCII )
   {
      printAscii( fptr, isEbcdic );
   }
   else // default
   {
      print( fptr, isEbcdic );
   }

   fclose (fptr);

   return 0;

} // End: main( ... )
<commit_msg>Added stdin capability<commit_after>//*******************************************************************
// Copyright (C) 2000 ImageLinks Inc.
//
// License:  See top level LICENSE.txt file.
//
// Author: Ken Melero
//         Originally written by Oscar Kramer.
//
// Description:  This app displays a binary file in a nice
//               formatted view.  Very helpful for finding offsets of
//               binary headers.
//
//********************************************************************
// $Id: ossim-btoa.cpp 22209 2013-03-29 13:38:38Z dburken $

#include <ossim/base/ossimArgumentParser.h>
#include <ossim/base/ossimEbcdicToAscii.h>

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

// Regular print with offset, hex, and ascii section.
static void print( FILE* fptr, bool isEbcdic )
{
   int           offset = 0;
   unsigned char bin_data[16];
   char          asc_data[17];
   int           hex_data[16];
   int           nbytes;
   int           i;

   asc_data[16] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, 16, 1, fptr);
      for(i=0; i<16; i++)
      {
         hex_data[i] = (int) bin_data[i];

         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf("%06d  %02X %02X %02X %02X %02X %02X %02X %02X  "
             "%02X %02X %02X %02X %02X %02X %02X %02X  %16s\n", offset,
             hex_data[0],  hex_data[1],  hex_data[2],  hex_data[3],
             hex_data[4],  hex_data[5],  hex_data[6],  hex_data[7],
             hex_data[8],  hex_data[9],  hex_data[10], hex_data[11],
             hex_data[12], hex_data[13], hex_data[14], hex_data[15],
             asc_data);

      offset += 16;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // End: print(...)

// Wide print offset and ascii section only.
static void printWide( FILE* fptr, bool isEbcdic )
{
   const int WIDTH = 64;

   int           offset = 0;
   unsigned char bin_data[WIDTH];
   char          asc_data[WIDTH+1];
   int           nbytes;
   int           i = 0;

   asc_data[WIDTH] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, WIDTH, 1, fptr);
      for( i = 0; i < WIDTH; ++i )
      {
         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf("%06d  %64s\n", offset, asc_data);

      offset += WIDTH;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // End printWide( ... )

// Wide print ascii section only.
static void printAscii( FILE* fptr, bool isEbcdic )
{
   const int WIDTH = 80;

   int           offset = 0;
   unsigned char bin_data[WIDTH];
   char          asc_data[WIDTH+1];
   int           nbytes;
   int           i = 0;

   asc_data[WIDTH] = '\0';

   ossimEbcdicToAscii* e2a = 0;
   if ( isEbcdic )
   {
      e2a = new ossimEbcdicToAscii;
   }

   while (!feof(fptr))
   {
      nbytes = (int)fread(bin_data, WIDTH, 1, fptr);
      for( i = 0; i < WIDTH; ++i )
      {
         if (e2a)
         {
            bin_data[i] = e2a->ebcdicToAscii(bin_data[i]);
         }

         if ((bin_data[i] >= 0x20) && (bin_data[i] < 0x7F)) // 0x7F is a DEL
         {
            asc_data[i] = bin_data[i];
         }
         else
         {
            asc_data[i] = '.';
         }
      }

      printf( "%80s\n", asc_data );

      offset += WIDTH;
   }

   if (e2a)
   {
      delete e2a;
      e2a = 0;
   }

} // printAscii

int main(int argc, char** argv)
{
   // Parse the args:
   ossimArgumentParser argumentParser(&argc, argv);

   enum PrintMode
   {
      ALL   = 0, // offsets hex ascii - default
      WIDE  = 1, // offsets ascii     - "-w" option
      ASCII = 2  // ascii             - "-a" option
   };

   // Check for options:
   bool isEbcdic = false;
   PrintMode mode = ALL;

   if ( argumentParser.read("-e") )
   {
      isEbcdic = true;
   }
   if ( argumentParser.read("-w") )
   {
      mode = WIDE;
   }
   if ( argumentParser.read("-a") )
   {
      if ( mode != ALL )
      {
         std::cerr << "Cannot use -a and -w options." << std::endl;
         return -1;
      }
      mode = ASCII;
   }

   if ( argumentParser.read("-h") || argumentParser.read("--help"))
   {
      std::cout << "\nDisplays a binary file as ASCII/hexadecimal. If no input file is provided, then\n"
                << "input is taken from stdin. Non-ascii characters are printed as dot in ascii output.\n"
                << "Default mode prints offsets, hex and ascii data.\n\n"
                << "Usage: btoa [options] [<binary_file>]\n\n"
                << "Options:\n\n"
                << "  -e          Indicates text characters are ebcdic and should be"
                << "              converted to ascii.\n"
                << "  -h, --help  Shows this usage\n"
                << "  -a          Ascii mode, prints 64 characters wide with no offset or hex data.\n"
                << "  -w          Wide mode, prints offset and 64 characters wide with no hex data.\n"
                << std::endl;
      return 0;
   }

   FILE* fptr = 0;
   if (argumentParser.argc() > 1)
   {
      fptr = fopen(argv[argumentParser.argc() - 1], "rb");
      if (fptr == 0)
      {
         std::cout << "\nError opening file " << argv[argumentParser.argc() - 1]
                   << std::endl << std::endl;
         return -1;
      }
   }
   else
      fptr = stdin;

   if ( mode == WIDE )
   {
      printWide( fptr, isEbcdic );
   }
   else if ( mode == ASCII )
   {
      printAscii( fptr, isEbcdic );
   }
   else // default
   {
      print( fptr, isEbcdic );
   }

   fclose (fptr);

   return 0;

} // End: main( ... )
<|endoftext|>


<commit_before>#include <sirius.h>

using namespace sirius;

void create_supercell(cmd_args& args__)
{
    matrix3d<int> scell;
    std::stringstream s(args__.value<std::string>("supercell"));
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++) s >> scell(j, i);
    }

    std::cout << std::endl;
    std::cout << "supercell vectors (lattice coordinates) : " << std::endl;
    for (int i = 0; i < 3; i++)
    {
        std::cout << "A" << i << " : ";
        for (int j = 0; j < 3; j++) std::cout << scell(j, i) << " ";
        std::cout << std::endl;
    }

    Simulation_context ctx("sirius.json", mpi_comm_self());

    matrix3d<double> scell_lattice_vectors = ctx.unit_cell().lattice_vectors() * matrix3d<double>(scell);

    std::cout << "supercell vectors (Cartesian coordinates) : " << std::endl;
    for (int i = 0; i < 3; i++)
    {
        std::cout << "A" << i << " : ";
        for (int x = 0; x < 3; x++) std::cout << scell_lattice_vectors(x, i) << " ";
        std::cout << std::endl;
    }

    std::cout << "volume ratio : " << std::abs(matrix3d<int>(scell).det()) << std::endl;

    Simulation_context ctx_sc(mpi_comm_self());

    vector3d<double> a0, a1, a2;
    for (int x = 0; x < 3; x++)
    {
        a0[x] = scell_lattice_vectors(x, 0);
        a1[x] = scell_lattice_vectors(x, 1);
        a2[x] = scell_lattice_vectors(x, 2);
    }
    ctx_sc.unit_cell().set_lattice_vectors(a0, a1, a2);

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();
        ctx_sc.unit_cell().add_atom_type(label, "");
    }

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();

        for (int i = 0; i < ctx.unit_cell().atom_type(iat).num_atoms(); i++)
        {
            int ia = ctx.unit_cell().atom_type(iat).atom_id(i);
            auto va = ctx.unit_cell().atom(ia).position();

            for (int i0 = -10; i0 <= 10; i0++)
            {
                for (int i1 = -10; i1 <= 10; i1++)
                {
                    for (int i2 = -10; i2 <= 10; i2++)
                    {
                        vector3d<double> T(i0, i1, i2);
                        vector3d<double> vc = ctx.unit_cell().get_cartesian_coordinates(va + T);
                        vector3d<double> vf = ctx_sc.unit_cell().get_fractional_coordinates(vc);

                        auto vr = reduce_coordinates(vf);
                        bool add_atom = (ctx_sc.unit_cell().atom_id_by_position(vr.first) == -1);
                        //==if (add_atom && iat == 2)
                        //=={
                        //==    double r = type_wrapper<double>::random();
                        //==    if (r < 0.99) add_atom = false;
                        //==}

                        if (add_atom) ctx_sc.unit_cell().add_atom(label, vr.first);
                    }
                }
            }
        }
    }
    printf("number of atoms in the supercell: %i\n", ctx_sc.unit_cell().num_atoms());

    ctx_sc.unit_cell().get_symmetry();
    ctx_sc.unit_cell().print_info(4);
    ctx_sc.unit_cell().write_cif();
    json dict;
    dict["unit_cell"] = ctx_sc.unit_cell().serialize();
    if (mpi_comm_world().rank() == 0) {
        std::ofstream ofs("unit_cell.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }
}

void find_primitive()
{
    Simulation_context ctx("sirius.json", mpi_comm_self());

    double lattice[3][3];
    for (int i: {0, 1, 2}) {
        for (int j: {0, 1, 2}) {
            lattice[i][j] = ctx.unit_cell().lattice_vector(j)[i];
        }
    }
    mdarray<double, 2> positions(3, 4 * ctx.unit_cell().num_atoms());
    mdarray<int, 1> types(4 * ctx.unit_cell().num_atoms());
    for (int ia = 0; ia < ctx.unit_cell().num_atoms(); ia++) {
        for (int x: {0, 1, 2}) {
            positions(x, ia) = ctx.unit_cell().atom(ia).position()[x];
            types(ia) = ctx.unit_cell().atom(ia).type_id();
        }
    }

    int nat_new = spg_find_primitive(lattice, (double(*)[3])&positions(0, 0), &types[0], ctx.unit_cell().num_atoms(), 1e-4);
    printf("new number of atoms: %i\n", nat_new);

    Simulation_context ctx_new(mpi_comm_self());

    vector3d<double> a0, a1, a2;
    for (int x = 0; x < 3; x++) {
        a0[x] = lattice[x][0];
        a1[x] = lattice[x][1];
        a2[x] = lattice[x][2];
    }
    ctx_new.unit_cell().set_lattice_vectors(a0, a1, a2);

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();
        ctx_new.unit_cell().add_atom_type(label, "");
    }

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++) {
        auto label = ctx.unit_cell().atom_type(iat).label();

        for (int i = 0; i < nat_new; i++) {
            if (types[i] == iat) {
                vector3d<double> p(positions(0, i), positions(1, i), positions(2, i));
                ctx_new.unit_cell().add_atom(label, p);
            }
        }
    }

    json dict;
    dict["unit_cell"] = ctx_new.unit_cell().serialize();
    if (mpi_comm_world().rank() == 0) {
        std::ofstream ofs("unit_cell.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }

}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--supercell=", "{string} transformation matrix (9 numbers)");
    args.register_key("--qe", "create input for QE");
    args.register_key("--find_primitive", "find a primitive cell");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);
    if (args.exist("supercell")) {
        create_supercell(args);
    }
    if (args.exist("find_primitive")) {
        find_primitive();
    }

    sirius::finalize();

//==
//==    if (args.exist("qe"))
//==    {
//==        int nat = 0;
//==        for (int iat = 0; iat < (int)iip.unit_cell_input_section_.labels_.size(); iat++)
//==            nat += (int)iip.unit_cell_input_section_.coordinates_[iat].size();
//==
//==        FILE* fout = fopen("pw.in", "w");
//==        fprintf(fout, "&control\ncalculation=\'scf\',\nrestart_mode=\'from_scratch\',\npseudo_dir = \'./\',\noutdir=\'./\',\nprefix = \'scf_\'\n/\n");
//==        fprintf(fout, "&system\nibrav=0, celldm(1)=1, ecutwfc=40, ecutrho = 300,\noccupations = \'smearing\', smearing = \'gauss\', degauss = 0.001,\n");
//==        fprintf(fout, "nat=%i ntyp=%i\n/\n", nat, (int)iip.unit_cell_input_section_.labels_.size());
//==        fprintf(fout, "&electrons\nconv_thr =  1.0d-11,\nmixing_beta = 0.7,\nelectron_maxstep = 100\n/\n");
//==        fprintf(fout, "ATOMIC_SPECIES\n");
//==        for (int iat = 0; iat < (int)iip.unit_cell_input_section_.labels_.size(); iat++)
//==            fprintf(fout, "%s 0.0 pp.UPF\n", iip.unit_cell_input_section_.labels_[iat].c_str());
//==
//==        fprintf(fout,"CELL_PARAMETERS\n");
//==        for (int i = 0; i < 3; i++)
//==        {
//==            for (int x = 0; x < 3; x++) fprintf(fout, "%18.8f", p.unit_cell()->lattice_vectors()(x, i));
//==            fprintf(fout, "\n");
//==        }
//==        fprintf(fout, "ATOMIC_POSITIONS (crystal)\n");
//==        for (int iat = 0; iat < (int)iip.unit_cell_input_section_.labels_.size(); iat++)
//==        {
//==            for (int ia = 0; ia < (int)iip.unit_cell_input_section_.coordinates_[iat].size(); ia++)
//==            {
//==                fprintf(fout, "%s  %18.8f %18.8f %18.8f\n", iip.unit_cell_input_section_.labels_[iat].c_str(),
//==                        iip.unit_cell_input_section_.coordinates_[iat][ia][0],
//==                        iip.unit_cell_input_section_.coordinates_[iat][ia][1],
//==                        iip.unit_cell_input_section_.coordinates_[iat][ia][2]);
//==            }
//==        }
//==        fprintf(fout, "K_POINTS (automatic)\n2 2 2  0 0 0\n");
//==
//==        fclose(fout);
//==
//==
//==
//==    }
//==    }
//==
//==    //p.unit_cell()->get_symmetry();
//==    //p.unit_cell()->print_info();
//==
//==    Platform::finalize();

}
<commit_msg>write qe input file<commit_after>#include <sirius.h>

using namespace sirius;

void create_supercell(cmd_args& args__)
{
    matrix3d<int> scell;
    std::stringstream s(args__.value<std::string>("supercell"));
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++) s >> scell(j, i);
    }

    std::cout << std::endl;
    std::cout << "supercell vectors (lattice coordinates) : " << std::endl;
    for (int i = 0; i < 3; i++)
    {
        std::cout << "A" << i << " : ";
        for (int j = 0; j < 3; j++) std::cout << scell(j, i) << " ";
        std::cout << std::endl;
    }

    Simulation_context ctx("sirius.json", mpi_comm_self());

    matrix3d<double> scell_lattice_vectors = ctx.unit_cell().lattice_vectors() * matrix3d<double>(scell);

    std::cout << "supercell vectors (Cartesian coordinates) : " << std::endl;
    for (int i = 0; i < 3; i++)
    {
        std::cout << "A" << i << " : ";
        for (int x = 0; x < 3; x++) std::cout << scell_lattice_vectors(x, i) << " ";
        std::cout << std::endl;
    }

    std::cout << "volume ratio : " << std::abs(matrix3d<int>(scell).det()) << std::endl;

    Simulation_context ctx_sc(mpi_comm_self());

    vector3d<double> a0, a1, a2;
    for (int x = 0; x < 3; x++)
    {
        a0[x] = scell_lattice_vectors(x, 0);
        a1[x] = scell_lattice_vectors(x, 1);
        a2[x] = scell_lattice_vectors(x, 2);
    }
    ctx_sc.unit_cell().set_lattice_vectors(a0, a1, a2);

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();
        ctx_sc.unit_cell().add_atom_type(label, "");
    }

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();

        for (int i = 0; i < ctx.unit_cell().atom_type(iat).num_atoms(); i++)
        {
            int ia = ctx.unit_cell().atom_type(iat).atom_id(i);
            auto va = ctx.unit_cell().atom(ia).position();

            for (int i0 = -10; i0 <= 10; i0++)
            {
                for (int i1 = -10; i1 <= 10; i1++)
                {
                    for (int i2 = -10; i2 <= 10; i2++)
                    {
                        vector3d<double> T(i0, i1, i2);
                        vector3d<double> vc = ctx.unit_cell().get_cartesian_coordinates(va + T);
                        vector3d<double> vf = ctx_sc.unit_cell().get_fractional_coordinates(vc);

                        auto vr = reduce_coordinates(vf);
                        bool add_atom = (ctx_sc.unit_cell().atom_id_by_position(vr.first) == -1);
                        //==if (add_atom && iat == 2)
                        //=={
                        //==    double r = type_wrapper<double>::random();
                        //==    if (r < 0.99) add_atom = false;
                        //==}

                        if (add_atom) ctx_sc.unit_cell().add_atom(label, vr.first);
                    }
                }
            }
        }
    }
    printf("number of atoms in the supercell: %i\n", ctx_sc.unit_cell().num_atoms());

    ctx_sc.unit_cell().get_symmetry();
    ctx_sc.unit_cell().print_info(4);
    ctx_sc.unit_cell().write_cif();
    json dict;
    dict["unit_cell"] = ctx_sc.unit_cell().serialize();
    if (mpi_comm_world().rank() == 0) {
        std::ofstream ofs("unit_cell.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }
}

void find_primitive()
{
    Simulation_context ctx("sirius.json", mpi_comm_self());

    double lattice[3][3];
    for (int i: {0, 1, 2}) {
        for (int j: {0, 1, 2}) {
            lattice[i][j] = ctx.unit_cell().lattice_vector(j)[i];
        }
    }
    mdarray<double, 2> positions(3, 4 * ctx.unit_cell().num_atoms());
    mdarray<int, 1> types(4 * ctx.unit_cell().num_atoms());
    for (int ia = 0; ia < ctx.unit_cell().num_atoms(); ia++) {
        for (int x: {0, 1, 2}) {
            positions(x, ia) = ctx.unit_cell().atom(ia).position()[x];
            types(ia) = ctx.unit_cell().atom(ia).type_id();
        }
    }

    int nat_new = spg_find_primitive(lattice, (double(*)[3])&positions(0, 0), &types[0], ctx.unit_cell().num_atoms(), 1e-4);
    printf("new number of atoms: %i\n", nat_new);

    Simulation_context ctx_new(mpi_comm_self());

    vector3d<double> a0, a1, a2;
    for (int x = 0; x < 3; x++) {
        a0[x] = lattice[x][0];
        a1[x] = lattice[x][1];
        a2[x] = lattice[x][2];
    }
    ctx_new.unit_cell().set_lattice_vectors(a0, a1, a2);

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++)
    {
        auto label = ctx.unit_cell().atom_type(iat).label();
        ctx_new.unit_cell().add_atom_type(label, "");
    }

    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++) {
        auto label = ctx.unit_cell().atom_type(iat).label();

        for (int i = 0; i < nat_new; i++) {
            if (types[i] == iat) {
                vector3d<double> p(positions(0, i), positions(1, i), positions(2, i));
                ctx_new.unit_cell().add_atom(label, p);
            }
        }
    }

    json dict;
    dict["unit_cell"] = ctx_new.unit_cell().serialize();
    if (mpi_comm_world().rank() == 0) {
        std::ofstream ofs("unit_cell.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }

}

void create_qe_input()
{
    Simulation_context ctx("sirius.json", mpi_comm_self());

    FILE* fout = fopen("pw.in", "w");
    fprintf(fout, "&control\ncalculation=\'scf\',\nrestart_mode=\'from_scratch\',\npseudo_dir = \'./\',\noutdir=\'./\',\nprefix = \'scf_\'\n/\n");
    fprintf(fout, "&system\nibrav=0, celldm(1)=1, ecutwfc=40, ecutrho = 300,\noccupations = \'smearing\', smearing = \'gauss\', degauss = 0.001,\n");
    fprintf(fout, "nat=%i ntyp=%i\n/\n", ctx.unit_cell().num_atom_types(), ctx.unit_cell().num_atoms());
    fprintf(fout, "&electrons\nconv_thr =  1.0d-11,\nmixing_beta = 0.7,\nelectron_maxstep = 100\n/\n");
    fprintf(fout, "ATOMIC_SPECIES\n");
    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++) {
        fprintf(fout, "%s 0.0 pp.UPF\n", ctx.unit_cell().atom_type(iat).label().c_str());
    }

    fprintf(fout,"CELL_PARAMETERS\n");
    for (int i = 0; i < 3; i++) {
        for (int x = 0; x < 3; x++) {
            fprintf(fout, "%18.8f", ctx.unit_cell().lattice_vector(i)[x]);
        }
        fprintf(fout, "\n");
    }
    fprintf(fout, "ATOMIC_POSITIONS (crystal)\n");
    for (int iat = 0; iat < ctx.unit_cell().num_atom_types(); iat++) {
        for (int ia = 0; ia < ctx.unit_cell().atom_type(iat).num_atoms(); ia++) {
            int id = ctx.unit_cell().atom_type(iat).atom_id(ia);
            fprintf(fout, "%s  %18.8f %18.8f %18.8f\n", ctx.unit_cell().atom_type(iat).label().c_str(),
                    ctx.unit_cell().atom(id).position()[0],
                    ctx.unit_cell().atom(id).position()[1],
                    ctx.unit_cell().atom(id).position()[2]);
        }
    }
    fprintf(fout, "K_POINTS (automatic)\n2 2 2  0 0 0\n");

    fclose(fout);
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--supercell=", "{string} transformation matrix (9 numbers)");
    args.register_key("--qe", "create input for QE");
    args.register_key("--find_primitive", "find a primitive cell");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);
    if (args.exist("supercell")) {
        create_supercell(args);
    }
    if (args.exist("find_primitive")) {
        find_primitive();
    }
    if (args.exist("qe")) {
        create_qe_input();
    }

    sirius::finalize();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <ctime>
#include <fstream>
#include <string>
#include <limits>

#include "../include/Game.h"
#include "../include/Common.h"
#include "../include/Console.h"

#include "../include/PlayerTypes/PlayerTypes.h"
#include "../include/EnemyTypes/EnemyTypes.h"

using namespace std;
using namespace Common;

// To avoid conflict with numeric_limits<streamsize>::max used in Game::GetChoice()
#ifdef max
#undef max
#endif

void Game::MainMenu(){
    // Main menu. Loops until you start
    // a game or quit.
	    for (int choice=0; choice!=3;){
        choice = GetChoice(MenuType::eMain);
        switch(choice){
			case 1:
           		StartGame();
				break;
			case 2:
				HowToPlay();
				break;
			case 3:
				break;
        }
    }
}

string Game::InitializePlayerName() {
	ClearScreen();
	string name;
	cout << "What is your name?"
		<< endl << endl
		<< "> ";

  cin.ignore();
	getline(cin,name); // Change to full name
	return name;
}

int Game::InitializePlayerClass() {
	// Initializes the player's class through user choice.
	int player_class = 0;
	player_class = GetChoice(MenuType::ePlayerClass);
	SetPlayerClass(player_class);
	return player_class;
}

void Game::SetPlayerClass(int player_class) {
	// Sets the Player class according to player code given.
	switch (player_class) {
	case 1:
		// Player's class is a warrior.
		_Player = new Warrior;
		break;
	case 2:
		// Player's class is a rogue.
		_Player = new Rogue;
		break;
	case 3:
		// Player's class is a healer.
		_Player = new Healer;
		break;
	case 4:
		// Player's class is a debugger.
		// Used to easily defeat enemies. Only for development purposes.
		_Player = new Debugger;
		break;
	case 5:
		// You are Saitama.
		// Do I have to explain??
		_Player = new Saitama;
		break;
	default:
		// If input does not equal any of the cases, the default class is a warrior.
		_Player = new Warrior;
		break;
	}
}

void Game::SetPlayerData(){
	/* Data initialized in order of:
	* class code
	* name
	* level
	* experience
	* health
	* arrows
	* bombs
	* potions
	* whetstones
	* weaponstrength
	* coins
	*/

	ifstream ReadData;
	ReadData.open("data.txt");

	// Runs if user has never played the game before or data is not found.
	if (!ReadData) {
		ReadData.close();
		ofstream WriteData;
		WriteData.open("data.txt");

		WriteData << InitializePlayerClass() << endl
			<< InitializePlayerName() << endl
			<< 1 << endl
			<< 0 << endl
			<< 100 << endl
			<< 10 << endl
			<< 1 << endl
			<< 1 << endl
			<< 1 << endl
			<< 100 << endl
			<< 0;
		WriteData.close();
	}

	else {
		// Initializes player type from class code given in data.txt
		int player_class;
		ReadData >> player_class;
		SetPlayerClass(player_class);
		ReadData.close();
	}
}

void Game::SetEnemy(){
    // Generates a random integer to determine class of the enemy.
    // The abstract class Enemy is morphed with one of its child classes.

    EnemyType selector = EnemyType(rand()%etNumEnemyTypes);
    switch(selector){
        case etCrab:
            // Enemy is a crab.
            _Enemy = new Crab;
            break;
        case etGiantCrab:
            // Enemy is a giant crab.
            _Enemy = new GiantCrab;
            break;
        case etSquid:
            // Enemy is a squid.
            _Enemy = new Squid;
            break;
        case etGiantSquid:
            // Enemy is a giant squid.
            _Enemy = new GiantSquid;
            break;
		case etLich:
			// Enemy is a Lich
			_Enemy = new Lich;
			break;
		case etPutnafer:
			// Enemy is a Putnafer
			_Enemy = new Putnafer;
			break;
        case etZombie:
            // Enemy is a Zombie
            _Enemy = new Zombie;
            break;
		case etVampire:
			// Enemy is a Vampire
			_Enemy = new Vampire;
			break;
		case etWerewolf:
			// Enemy is a Werewolf
			_Enemy = new Werewolf;
			break;
		case etGoblin:
			// Enemy is a Goblin
			_Enemy = new Goblin;
			break;
		case etGargoyle:
			// Enemy is a Goblin
			_Enemy = new Gargoyle;
			break;
        default:
            // If the above cases do not match the selector for any reason,
            // the enemy defaults on the crab class.
            _Enemy = new Crab;
            break;
    }
    // Simply prints that the enemy's class was encountered.
	ColourPrint(_Enemy->GetName(), Console::DarkGrey);
    cout << " encountered!" << endl << endl;
    Sleep(SLEEP_MS);
}

bool Game::PlayAgain(){
    // Returns a bool value to determine if the player wants to play again.

    char choice;
    cout << "Keep going? (y/n)" << endl << endl;
    choice = (char)input();
    // Returns true if the player says yes (Y, y, 1).
    if (choice == 'y' || choice == 'Y' || choice == '1') return true;
    // Returns false otherwise, regardless of choice=='n'.
    return false;
}

void Game::Intermission(){
    // Saves game in case player unexpectedly quits (uses X instead of
    // in-game quit.
    _Player->SaveGame();

    // Loops until the player starts another battle or they quit (IsPlaying=false).
    for (int choice=0; IsPlaying;){
        ClearScreen();
        cout << "*--------- Intermission ----------* " << endl << endl;

	_Player->DisplayInventory();
        cout << "1) Start battle" << endl;
        cout << "2) Store" << endl;
        cout << "3) Gamble" << endl;
	cout << "4) Use Item" << endl;
        cout << "5) Quit" << endl << endl;

        choice = input();

        switch(choice){
        case 1:
            // Returns to StartGame()'s loop, calling Battle().
            return;
        case 2:
            // Goes to the store where the player can buy items.
            /// Currently in working progress.
            _Store.StoreFront(_Player);
            break;
        case 3:
            // Goes to the gambling arena.
            // _Player is passed in to add items won to the player inventory.
            _Gambling.Gamble(_Player);
            break;
	case 4:
	    _Player->UseItem();
	    _Player->SaveGame();
	    break;
        case 5:
            // Breaks the loop in StartGame(), going back to MainMenu().
            IsPlaying=false;
	    break;
        }
    }
}

void Game::StartGame(){
    // Starts the game by initializing values for a new game.

    // Seeds the random number generator for pseudo-random numbers.
    srand((unsigned int)time(NULL));
    IsPlaying=true;

    // SetPlayerData() initializes the variables in this end.
    ClearScreen();
    SetPlayerData();

	// This initializes the variables on the Player end.
    ClearScreen();
    _Player->SetPlayerData();

    // Loops while the game is still playing.
    // Alternates between battles and intermission (gambling, store, et)
    while(IsPlaying){
		Intermission();
		if (!IsPlaying)
			break;
		Battle();
    }

    // Saves the player's data to an external file before quitting.
    _Player->SaveGame();
}

void Game::Battle(){
    ClearScreen();
    // Uses random integers to determine class of the enemy.
    SetEnemy();

    // Loops the actual battle while playing.
    while(IsPlaying){
        ClearScreen();
        // Displays the name and health bar of the player and enemy.
        // The Enemy* argument is to display the enemy's
        // name. Explained more in _Player->DisplayHealthBar().
        _Player->DisplayHUD(_Enemy);
        _Enemy->DisplayHUD();

        // Player's turn to attack Enemy.
        _Enemy->TakeDamage(_Player->Attack());
        // Pauses console and ignores user input for SLEEP_MS milliseconds.
        Sleep(SLEEP_MS);

        // Leaves battle if player chooses to.
        if (!IsPlaying){
            IsPlaying = true;
            return;
        }

        // Executes when the enemy's health is 0 or below.
        if (_Enemy->IsDead()){
            // Adds drops to player's inventory from defeated enemy.
            _Player->AddToInventory(_Enemy->GetDrops());
            // Adds points to player's experience.
            _Player->AddExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			// If player wants to battle again, it breaks the loop and uses tail recursion to play again.
            if (PlayAgain()) break;
            // Returns to StartGame()'s loop, and executes Intermission().
            return;
        }

        // Enemy's turn to attack player.
        _Player->TakeDamage(_Enemy->Attack());
        Sleep(SLEEP_MS);

        // Executes when player's health is 0 or below.
        if (_Player->IsDead()){
            // Player loses the amount of experience points gained when you defeat the enemy.
            _Player->LoseExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			if (PlayAgain()) break;
            return;
        }
    }
    Battle();
}

void Game::HowToPlay() {

	GetChoice(MenuType::eHowToPlay);
}

int Game::GetChoice(MenuType menuType)
{
	DisplayMenu(menuType);
	int choice = -1;
	while (!(cin >> choice)) {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Invalid input.  Please try again.";
		Sleep(SLEEP_MS);
		DisplayMenu(menuType);
	}
	return choice;
}

void Game::DisplayMenu(MenuType menuType)
{
	ClearScreen();
	switch (menuType)
	{
	case Game::eMain:
		cout << "========== TURN-BASED FIGHTING GAME ==========" << endl << endl
			<< "1) Start Game" << endl
			<< "2) How to play" << endl
			<< "3) Exit" << endl << endl << "> ";
		break;
	case Game::ePlayerClass:
		cout << endl
			<< "Which class do you want to play as?" << endl
			<< "1) Warrior (high damage, low healing capabilities)" << endl
			<< "2) Rogue (moderate damage, moderate healing capabilities)" << endl
			<< "3) Healer (low damage, high healing capabilities)" << endl
			<< "4) Debugger (INFINITE DAMAGE!!!!)" << endl
			<< "5) Saitama (self-explanatory)" << endl
			<< endl << endl
			<< "> ";
		break;
	case Game::eHowToPlay:
		cout << "============== HOW TO PLAY ==============" << endl << endl
			<< "Turn is a turn-based RPG game." << endl
			<< "Create your character and start playing." << endl
			<< "For playing you have to choose what to do by typing" << endl
			<< "the corresponding number." << endl
			<< "You can perform actions and use items." << endl << endl
			<< "-- Actions --" << endl
			<< "Attack: Regular attack" << endl
			<< "Risk Attack: Attack deals more damage, but with a chance of missing" << endl
			<< "Heal: Restore an amount of your HP" << endl
			<< "Flee: Run away from battle" << endl << endl
			<< "-- Items --" << endl
			<< "Bombs: Deals 50HP to your opponent with no chance of missing" << endl
			<< "Arrows: Deals 10-15HP to your opponent with no chance of missing" << endl
			<< "Potion: Replenishes your HP to 100" << endl
			<< "Whetstone: Restores your weapon's sharpness." << endl << endl
			<< "Good luck and have fun!" << endl << endl
			<< "1) Quit" << endl << endl << "> ";
		break;
	default:
		break;
	}
}
<commit_msg>change default menu option to 0<commit_after>#include <iostream>
#include <ctime>
#include <fstream>
#include <string>
#include <limits>

#include "../include/Game.h"
#include "../include/Common.h"
#include "../include/Console.h"

#include "../include/PlayerTypes/PlayerTypes.h"
#include "../include/EnemyTypes/EnemyTypes.h"

using namespace std;
using namespace Common;

// To avoid conflict with numeric_limits<streamsize>::max used in Game::GetChoice()
#ifdef max
#undef max
#endif

void Game::MainMenu(){
    // Main menu. Loops until you start
    // a game or quit.
	    for (int choice=0; choice!=3;){
        choice = GetChoice(MenuType::eMain);
        switch(choice){
			case 1:
           		StartGame();
				break;
			case 2:
				HowToPlay();
				break;
			case 3:
				break;
        }
    }
}

string Game::InitializePlayerName() {
	ClearScreen();
	string name;
	cout << "What is your name?"
		<< endl << endl
		<< "> ";

  cin.ignore();
	getline(cin,name); // Change to full name
	return name;
}

int Game::InitializePlayerClass() {
	// Initializes the player's class through user choice.
	int player_class = 0;
	player_class = GetChoice(MenuType::ePlayerClass);
	SetPlayerClass(player_class);
	return player_class;
}

void Game::SetPlayerClass(int player_class) {
	// Sets the Player class according to player code given.
	switch (player_class) {
	case 1:
		// Player's class is a warrior.
		_Player = new Warrior;
		break;
	case 2:
		// Player's class is a rogue.
		_Player = new Rogue;
		break;
	case 3:
		// Player's class is a healer.
		_Player = new Healer;
		break;
	case 4:
		// Player's class is a debugger.
		// Used to easily defeat enemies. Only for development purposes.
		_Player = new Debugger;
		break;
	case 5:
		// You are Saitama.
		// Do I have to explain??
		_Player = new Saitama;
		break;
	default:
		// If input does not equal any of the cases, the default class is a warrior.
		_Player = new Warrior;
		break;
	}
}

void Game::SetPlayerData(){
	/* Data initialized in order of:
	* class code
	* name
	* level
	* experience
	* health
	* arrows
	* bombs
	* potions
	* whetstones
	* weaponstrength
	* coins
	*/

	ifstream ReadData;
	ReadData.open("data.txt");

	// Runs if user has never played the game before or data is not found.
	if (!ReadData) {
		ReadData.close();
		ofstream WriteData;
		WriteData.open("data.txt");

		WriteData << InitializePlayerClass() << endl
			<< InitializePlayerName() << endl
			<< 1 << endl
			<< 0 << endl
			<< 100 << endl
			<< 10 << endl
			<< 1 << endl
			<< 1 << endl
			<< 1 << endl
			<< 100 << endl
			<< 0;
		WriteData.close();
	}

	else {
		// Initializes player type from class code given in data.txt
		int player_class;
		ReadData >> player_class;
		SetPlayerClass(player_class);
		ReadData.close();
	}
}

void Game::SetEnemy(){
    // Generates a random integer to determine class of the enemy.
    // The abstract class Enemy is morphed with one of its child classes.

    EnemyType selector = EnemyType(rand()%etNumEnemyTypes);
    switch(selector){
        case etCrab:
            // Enemy is a crab.
            _Enemy = new Crab;
            break;
        case etGiantCrab:
            // Enemy is a giant crab.
            _Enemy = new GiantCrab;
            break;
        case etSquid:
            // Enemy is a squid.
            _Enemy = new Squid;
            break;
        case etGiantSquid:
            // Enemy is a giant squid.
            _Enemy = new GiantSquid;
            break;
		case etLich:
			// Enemy is a Lich
			_Enemy = new Lich;
			break;
		case etPutnafer:
			// Enemy is a Putnafer
			_Enemy = new Putnafer;
			break;
        case etZombie:
            // Enemy is a Zombie
            _Enemy = new Zombie;
            break;
		case etVampire:
			// Enemy is a Vampire
			_Enemy = new Vampire;
			break;
		case etWerewolf:
			// Enemy is a Werewolf
			_Enemy = new Werewolf;
			break;
		case etGoblin:
			// Enemy is a Goblin
			_Enemy = new Goblin;
			break;
		case etGargoyle:
			// Enemy is a Goblin
			_Enemy = new Gargoyle;
			break;
        default:
            // If the above cases do not match the selector for any reason,
            // the enemy defaults on the crab class.
            _Enemy = new Crab;
            break;
    }
    // Simply prints that the enemy's class was encountered.
	ColourPrint(_Enemy->GetName(), Console::DarkGrey);
    cout << " encountered!" << endl << endl;
    Sleep(SLEEP_MS);
}

bool Game::PlayAgain(){
    // Returns a bool value to determine if the player wants to play again.

    char choice;
    cout << "Keep going? (y/n)" << endl << endl;
    choice = (char)input();
    // Returns true if the player says yes (Y, y, 1).
    if (choice == 'y' || choice == 'Y' || choice == '1') return true;
    // Returns false otherwise, regardless of choice=='n'.
    return false;
}

void Game::Intermission(){
    // Saves game in case player unexpectedly quits (uses X instead of
    // in-game quit.
    _Player->SaveGame();

    // Loops until the player starts another battle or they quit (IsPlaying=false).
    for (int choice=0; IsPlaying;){
        ClearScreen();
        cout << "*--------- Intermission ----------* " << endl << endl;

	_Player->DisplayInventory();
        cout << "1) Start battle" << endl;
        cout << "2) Store" << endl;
        cout << "3) Gamble" << endl;
	cout << "4) Use Item" << endl;
        cout << "0) Quit" << endl << endl;

        choice = input();

        switch(choice){
        case 1:
            // Returns to StartGame()'s loop, calling Battle().
            return;
        case 2:
            // Goes to the store where the player can buy items.
            /// Currently in working progress.
            _Store.StoreFront(_Player);
            break;
        case 3:
            // Goes to the gambling arena.
            // _Player is passed in to add items won to the player inventory.
            _Gambling.Gamble(_Player);
            break;
	case 4:
	    _Player->UseItem();
	    _Player->SaveGame();
	    break;
        case 5:
            // Breaks the loop in StartGame(), going back to MainMenu().
            IsPlaying=false;
	    break;
        }
    }
}

void Game::StartGame(){
    // Starts the game by initializing values for a new game.

    // Seeds the random number generator for pseudo-random numbers.
    srand((unsigned int)time(NULL));
    IsPlaying=true;

    // SetPlayerData() initializes the variables in this end.
    ClearScreen();
    SetPlayerData();

	// This initializes the variables on the Player end.
    ClearScreen();
    _Player->SetPlayerData();

    // Loops while the game is still playing.
    // Alternates between battles and intermission (gambling, store, et)
    while(IsPlaying){
		Intermission();
		if (!IsPlaying)
			break;
		Battle();
    }

    // Saves the player's data to an external file before quitting.
    _Player->SaveGame();
}

void Game::Battle(){
    ClearScreen();
    // Uses random integers to determine class of the enemy.
    SetEnemy();

    // Loops the actual battle while playing.
    while(IsPlaying){
        ClearScreen();
        // Displays the name and health bar of the player and enemy.
        // The Enemy* argument is to display the enemy's
        // name. Explained more in _Player->DisplayHealthBar().
        _Player->DisplayHUD(_Enemy);
        _Enemy->DisplayHUD();

        // Player's turn to attack Enemy.
        _Enemy->TakeDamage(_Player->Attack());
        // Pauses console and ignores user input for SLEEP_MS milliseconds.
        Sleep(SLEEP_MS);

        // Leaves battle if player chooses to.
        if (!IsPlaying){
            IsPlaying = true;
            return;
        }

        // Executes when the enemy's health is 0 or below.
        if (_Enemy->IsDead()){
            // Adds drops to player's inventory from defeated enemy.
            _Player->AddToInventory(_Enemy->GetDrops());
            // Adds points to player's experience.
            _Player->AddExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			// If player wants to battle again, it breaks the loop and uses tail recursion to play again.
            if (PlayAgain()) break;
            // Returns to StartGame()'s loop, and executes Intermission().
            return;
        }

        // Enemy's turn to attack player.
        _Player->TakeDamage(_Enemy->Attack());
        Sleep(SLEEP_MS);

        // Executes when player's health is 0 or below.
        if (_Player->IsDead()){
            // Player loses the amount of experience points gained when you defeat the enemy.
            _Player->LoseExperience(_Enemy->ReturnExperience());
			// Replenishes player's health for the next round.
			_Player->ReplenishHealth();

			if (PlayAgain()) break;
            return;
        }
    }
    Battle();
}

void Game::HowToPlay() {

	GetChoice(MenuType::eHowToPlay);
}

int Game::GetChoice(MenuType menuType)
{
	DisplayMenu(menuType);
	int choice = -1;
	while (!(cin >> choice)) {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Invalid input.  Please try again.";
		Sleep(SLEEP_MS);
		DisplayMenu(menuType);
	}
	return choice;
}

void Game::DisplayMenu(MenuType menuType)
{
	ClearScreen();
	switch (menuType)
	{
	case Game::eMain:
		cout << "========== TURN-BASED FIGHTING GAME ==========" << endl << endl
			<< "1) Start Game" << endl
			<< "2) How to play" << endl
			<< "0) Exit" << endl << endl << "> ";
		break;
	case Game::ePlayerClass:
		cout << endl
			<< "Which class do you want to play as?" << endl
			<< "1) Warrior (high damage, low healing capabilities)" << endl
			<< "2) Rogue (moderate damage, moderate healing capabilities)" << endl
			<< "3) Healer (low damage, high healing capabilities)" << endl
			<< "4) Debugger (INFINITE DAMAGE!!!!)" << endl
			<< "5) Saitama (self-explanatory)" << endl
			<< endl << endl
			<< "> ";
		break;
	case Game::eHowToPlay:
		cout << "============== HOW TO PLAY ==============" << endl << endl
			<< "Turn is a turn-based RPG game." << endl
			<< "Create your character and start playing." << endl
			<< "For playing you have to choose what to do by typing" << endl
			<< "the corresponding number." << endl
			<< "You can perform actions and use items." << endl << endl
			<< "-- Actions --" << endl
			<< "Attack: Regular attack" << endl
			<< "Risk Attack: Attack deals more damage, but with a chance of missing" << endl
			<< "Heal: Restore an amount of your HP" << endl
			<< "Flee: Run away from battle" << endl << endl
			<< "-- Items --" << endl
			<< "Bombs: Deals 50HP to your opponent with no chance of missing" << endl
			<< "Arrows: Deals 10-15HP to your opponent with no chance of missing" << endl
			<< "Potion: Replenishes your HP to 100" << endl
			<< "Whetstone: Restores your weapon's sharpness." << endl << endl
			<< "Good luck and have fun!" << endl << endl
			<< "1) Quit" << endl << endl << "> ";
		break;
	default:
		break;
	}
}
<|endoftext|>