<commit_before>/*
 * Copyright (C) 2010-2011, David Eklov
 * Copyright (C) 2011, Andreas Sandberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sys/time.h>
#include <uart/usf.h>
#include "pin.H"

KNOB<string> knob_filename(KNOB_MODE_WRITEONCE,
                           "pintool", "o", "foo.usf", "Output filename");
KNOB<UINT64> knob_begin_addr(KNOB_MODE_WRITEONCE,
                             "pintool", "b", "0", "Start tracing at this address");
KNOB<UINT64> knob_end_addr(KNOB_MODE_WRITEONCE,
                           "pintool", "e", "0", "Stop tracing at this address");
KNOB<BOOL> knob_detach(KNOB_MODE_WRITEONCE,
                       "pintool", "d", "0", "Stop pin at stop address");
KNOB<BOOL> knob_bzip2(KNOB_MODE_WRITEONCE,
                      "pintool", "c", "0", "Enable BZip2 compression");
KNOB<BOOL> knob_inst_time(KNOB_MODE_WRITEONCE,
                          "pintool", "i", "0", "Use instruction count as time base");

static int tracing = 0;
static unsigned long begin_addr = 0;
static unsigned long end_addr = 0;

static usf_file_t *usf_file = NULL;
static usf_atime_t inst_count = 0;
static usf_atime_t access_count = 0;

static VOID fini(INT32 code, VOID *v);

static void
start_trace()
{
    tracing = 1;
}

static void
stop_trace()
{
    tracing = 0;
    if (knob_detach) {
        fini(0, NULL);
        exit(0);
    }
}

static VOID
log_access(VOID *pc, VOID *addr, ADDRINT size, THREADID tid, UINT32 access_type)
{
    usf_event_t e;

    e.type = USF_EVENT_TRACE;
    e.u.trace.access.pc = (usf_addr_t)pc;
    e.u.trace.access.addr = (usf_addr_t)addr;
    e.u.trace.access.time = knob_inst_time ? inst_count : access_count;
    e.u.trace.access.tid = (usf_tid_t)tid;
    e.u.trace.access.len = (usf_alen_t)size;
    e.u.trace.access.type = (usf_atype_t)access_type;

    if (usf_append(usf_file, &e) != USF_ERROR_OK) {
        cerr << "USF: Failed to append event."  << endl;
        abort();
    }

    access_count++;
}

static VOID PIN_FAST_ANALYSIS_CALL
inc_inst_count()
{
    inst_count++;
}

static ADDRINT PIN_FAST_ANALYSIS_CALL
is_tracing()
{
    return tracing;
}

static VOID
instruction(INS ins, VOID *not_used)
{
    if (begin_addr && INS_Address(ins) == begin_addr)
        start_trace();
    if (end_addr && INS_Address(ins) == end_addr)
        stop_trace();

    UINT32 no_ops = INS_MemoryOperandCount(ins);

    for (UINT32 op = 0; op < no_ops; op++) {
        const UINT32 size = INS_MemoryOperandSize(ins, op);
	const bool is_rd = INS_MemoryOperandIsRead(ins, op);
	const bool is_wr = INS_MemoryOperandIsWritten(ins, op);
	const UINT32 atype =
	    is_rd && is_wr ? USF_ATYPE_RW :
	    (is_wr ? USF_ATYPE_WR : USF_ATYPE_RD);

        INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(is_tracing),
                         IARG_FAST_ANALYSIS_CALL,
                         IARG_END);
	INS_InsertThenCall(ins, IPOINT_BEFORE,
                           (AFUNPTR)log_access,
                           IARG_INST_PTR,
                           IARG_MEMORYOP_EA, op,
                           IARG_UINT32, size,
                           IARG_THREAD_ID,
                           IARG_UINT32, atype,
                           IARG_END);
    }

    /* Increase the instruction counter
     *
     * NOTE: This means that multiple memory acceses may happen at the
     * same time if using the instruction time base */
    INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(is_tracing),
                     IARG_FAST_ANALYSIS_CALL,
                     IARG_END);
    INS_InsertThenCall(ins, IPOINT_BEFORE,
                       AFUNPTR(inc_inst_count),
                       IARG_FAST_ANALYSIS_CALL,
                       IARG_END);
}

static int
init(int argc, char *argv[])
{
    const char *filename = knob_filename.Value().c_str();
    usf_header_t header;
    struct timeval tv;
    int target_argc = argc;
    char **target_argv = argv;

    memset(&header, 0, sizeof(header));

    begin_addr = knob_begin_addr;
    if (!begin_addr)
        tracing = 1;
    end_addr = knob_end_addr;

    header.version = USF_VERSION_CURRENT;
    header.compression = knob_bzip2.Value() ? USF_COMPRESSION_BZIP2 : USF_COMPRESSION_NONE;
    header.flags = USF_FLAG_NATIVE_ENDIAN | USF_FLAG_TRACE | USF_FLAG_DELTA |
        (knob_inst_time ? USF_FLAG_TIME_INSTRUCTIONS : USF_FLAG_TIME_ACCESSES);

    if (gettimeofday(&tv, NULL) == 0)
	header.time_begin = tv.tv_sec;
    else
	cerr << "Warning: Failed to get time of day, "
	     << "information not included in trace file." << endl;

    for (int i = 0; i < argc; i++) {
	if (!strcmp("--", argv[i])) {
	    target_argc = argc - i - 1;
	    target_argv = argv + i + 1;
	}
    }
    header.argc = target_argc;
    header.argv = target_argv;

    return usf_create(&usf_file, filename, &header) == USF_ERROR_OK ? 0 : -1;
}

static VOID
fini(INT32 code, VOID *v)
{
    cerr << "=== Trace statistics ===" << endl;
    cerr << "Instructions: " << inst_count << endl;
    cerr << "Memory accesses: " << access_count << endl;

    usf_close(usf_file);
}

static int
usage()
{
    cerr <<
        "This tool is a PIN tool to generate USF trace files.\n"
        "\n";

    cerr << KNOB_BASE::StringKnobSummary();

    cerr << endl;

    return -1;
}

int
main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv))
        return usage();

    if (init(argc, argv))
        return -1;

    INS_AddInstrumentFunction(instruction, 0);
    PIN_AddFiniFunction(fini, 0);

    PIN_StartProgram();
    return 0;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * c-file-style: "k&r"
 * End:
 */
<commit_msg>Add an option to stop tracing after a fixed no of instructions<commit_after>/*
 * Copyright (C) 2010-2011, David Eklov
 * Copyright (C) 2011, Andreas Sandberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sys/time.h>
#include <uart/usf.h>
#include "pin.H"

KNOB<string> knob_filename(KNOB_MODE_WRITEONCE,
                           "pintool", "o", "foo.usf", "Output filename");
KNOB<UINT64> knob_end_cnt(KNOB_MODE_WRITEONCE,
                             "pintool", "count", "0", "Number of accesses to trace");

KNOB<UINT64> knob_begin_addr(KNOB_MODE_WRITEONCE,
                             "pintool", "b", "0", "Start tracing at this address");
KNOB<UINT64> knob_end_addr(KNOB_MODE_WRITEONCE,
                           "pintool", "e", "0", "Stop tracing at this address");
KNOB<BOOL> knob_detach(KNOB_MODE_WRITEONCE,
                       "pintool", "d", "0", "Exit pin on stop condition");
KNOB<BOOL> knob_bzip2(KNOB_MODE_WRITEONCE,
                      "pintool", "c", "0", "Enable BZip2 compression");
KNOB<BOOL> knob_inst_time(KNOB_MODE_WRITEONCE,
                          "pintool", "i", "0", "Use instruction count as time base");

static int tracing = 0;
static unsigned long begin_addr = 0;
static unsigned long end_addr = 0;
static UINT64 end_cnt = (UINT64)-1;

static usf_file_t *usf_file = NULL;
static usf_atime_t inst_count = 0;
static usf_atime_t access_count = 0;

static VOID fini(INT32 code, VOID *v);

static void
start_trace()
{
    tracing = 1;
}

static void
stop_trace()
{
    tracing = 0;
    if (knob_detach) {
        fini(0, NULL);
        exit(0);
    }
}

static VOID
log_access(VOID *pc, VOID *addr, ADDRINT size, THREADID tid, UINT32 access_type)
{
    usf_event_t e;

    e.type = USF_EVENT_TRACE;
    e.u.trace.access.pc = (usf_addr_t)pc;
    e.u.trace.access.addr = (usf_addr_t)addr;
    e.u.trace.access.time = knob_inst_time ? inst_count : access_count;
    e.u.trace.access.tid = (usf_tid_t)tid;
    e.u.trace.access.len = (usf_alen_t)size;
    e.u.trace.access.type = (usf_atype_t)access_type;

    if (usf_append(usf_file, &e) != USF_ERROR_OK) {
        cerr << "USF: Failed to append event."  << endl;
        abort();
    }

    access_count++;
    if (access_count >= end_cnt)
        stop_trace();
}

static VOID PIN_FAST_ANALYSIS_CALL
inc_inst_count()
{
    inst_count++;
}

static ADDRINT PIN_FAST_ANALYSIS_CALL
is_tracing()
{
    return tracing;
}

static VOID
instruction(INS ins, VOID *not_used)
{
    if (begin_addr && INS_Address(ins) == begin_addr)
        start_trace();
    if (end_addr && INS_Address(ins) == end_addr)
        stop_trace();

    UINT32 no_ops = INS_MemoryOperandCount(ins);

    for (UINT32 op = 0; op < no_ops; op++) {
        const UINT32 size = INS_MemoryOperandSize(ins, op);
	const bool is_rd = INS_MemoryOperandIsRead(ins, op);
	const bool is_wr = INS_MemoryOperandIsWritten(ins, op);
	const UINT32 atype =
	    is_rd && is_wr ? USF_ATYPE_RW :
	    (is_wr ? USF_ATYPE_WR : USF_ATYPE_RD);

        INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(is_tracing),
                         IARG_FAST_ANALYSIS_CALL,
                         IARG_END);
	INS_InsertThenCall(ins, IPOINT_BEFORE,
                           (AFUNPTR)log_access,
                           IARG_INST_PTR,
                           IARG_MEMORYOP_EA, op,
                           IARG_UINT32, size,
                           IARG_THREAD_ID,
                           IARG_UINT32, atype,
                           IARG_END);
    }

    /* Increase the instruction counter
     *
     * NOTE: This means that multiple memory acceses may happen at the
     * same time if using the instruction time base */
    INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(is_tracing),
                     IARG_FAST_ANALYSIS_CALL,
                     IARG_END);
    INS_InsertThenCall(ins, IPOINT_BEFORE,
                       AFUNPTR(inc_inst_count),
                       IARG_FAST_ANALYSIS_CALL,
                       IARG_END);
}

static int
init(int argc, char *argv[])
{
    const char *filename = knob_filename.Value().c_str();
    usf_header_t header;
    struct timeval tv;
    int target_argc = argc;
    char **target_argv = argv;

    memset(&header, 0, sizeof(header));

    begin_addr = knob_begin_addr;
    if (!begin_addr)
        tracing = 1;
    end_addr = knob_end_addr;
    if (knob_end_cnt)
        end_cnt = knob_end_cnt;

    header.version = USF_VERSION_CURRENT;
    header.compression = knob_bzip2.Value() ? USF_COMPRESSION_BZIP2 : USF_COMPRESSION_NONE;
    header.flags = USF_FLAG_NATIVE_ENDIAN | USF_FLAG_TRACE | USF_FLAG_DELTA |
        (knob_inst_time ? USF_FLAG_TIME_INSTRUCTIONS : USF_FLAG_TIME_ACCESSES);

    if (gettimeofday(&tv, NULL) == 0)
	header.time_begin = tv.tv_sec;
    else
	cerr << "Warning: Failed to get time of day, "
	     << "information not included in trace file." << endl;

    for (int i = 0; i < argc; i++) {
	if (!strcmp("--", argv[i])) {
	    target_argc = argc - i - 1;
	    target_argv = argv + i + 1;
	}
    }
    header.argc = target_argc;
    header.argv = target_argv;

    return usf_create(&usf_file, filename, &header) == USF_ERROR_OK ? 0 : -1;
}

static VOID
fini(INT32 code, VOID *v)
{
    cerr << "=== Trace statistics ===" << endl;
    cerr << "Instructions: " << inst_count << endl;
    cerr << "Memory accesses: " << access_count << endl;

    usf_close(usf_file);
}

static int
usage()
{
    cerr <<
        "This tool is a PIN tool to generate USF trace files.\n"
        "\n";

    cerr << KNOB_BASE::StringKnobSummary();

    cerr << endl;

    return -1;
}

int
main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv))
        return usage();

    if (init(argc, argv))
        return -1;

    INS_AddInstrumentFunction(instruction, 0);
    PIN_AddFiniFunction(fini, 0);

    PIN_StartProgram();
    return 0;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * c-file-style: "k&r"
 * End:
 */
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen
// =============================================================================
//
// Base class for a vehicle powertrain.
//
// =============================================================================

#include "chrono_vehicle/ChPowertrain.h"

namespace chrono {
namespace vehicle {

ChPowertrain::ChPowertrain(const std::string& name)
    : ChPart(name),
      m_transmission_mode(TransmissionMode::AUTOMATIC),
      m_drive_mode(DriveMode::FORWARD),
      m_current_gear(-1),
      m_current_gear_ratio(1e20) {}

void ChPowertrain::Initialize(std::shared_ptr<ChChassis> chassis, std::shared_ptr<ChDriveline> driveline) {
    m_driveline = driveline;

    // Let the derived class specify the gear ratios
    std::vector<double> fwd;
    double rev;
    SetGearRatios(fwd, rev);
    assert(fwd.size() > 0);
    if (rev > 0)
        rev *= -1;
    m_gear_ratios.push_back(rev);
    m_gear_ratios.insert(m_gear_ratios.end(), fwd.begin(), fwd.end());

    // Initialize the transmission in 1st gear
    SetGear(1);
}

void ChPowertrain::ShiftUp() {
    if (m_transmission_mode == TransmissionMode::MANUAL &&  //
        m_drive_mode == DriveMode::FORWARD &&               //
        m_current_gear < m_gear_ratios.size() - 1) {
        SetGear(m_current_gear + 1);
    }
}

void ChPowertrain::ShiftDown() {
    if (m_transmission_mode == TransmissionMode::MANUAL &&  //
        m_drive_mode == DriveMode::FORWARD &&               //
        m_current_gear > 1) {
        SetGear(m_current_gear - 1);
    }
}

void ChPowertrain::SetGear(int gear) {
    assert(igear >= 0);
    assert(igear < m_gear_ratios.size());

    m_current_gear = gear;
    m_current_gear_ratio = m_gear_ratios[m_current_gear];
    OnGearShift();
}

void ChPowertrain::SetDriveMode(DriveMode mode) {
    if (m_drive_mode == mode)
        return;

    m_drive_mode = mode;

    switch (m_drive_mode) {
        case DriveMode::FORWARD:
            SetGear(1);
            break;
        case DriveMode::NEUTRAL:
            m_current_gear_ratio = 1e20;
            OnNeutralShift();
            break;
        case DriveMode::REVERSE:
            SetGear(0);
            break;
    }
}

}  // end namespace vehicle
}  // end namespace chrono
<commit_msg>Fix type in debug assert<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen
// =============================================================================
//
// Base class for a vehicle powertrain.
//
// =============================================================================

#include "chrono_vehicle/ChPowertrain.h"

namespace chrono {
namespace vehicle {

ChPowertrain::ChPowertrain(const std::string& name)
    : ChPart(name),
      m_transmission_mode(TransmissionMode::AUTOMATIC),
      m_drive_mode(DriveMode::FORWARD),
      m_current_gear(-1),
      m_current_gear_ratio(1e20) {}

void ChPowertrain::Initialize(std::shared_ptr<ChChassis> chassis, std::shared_ptr<ChDriveline> driveline) {
    m_driveline = driveline;

    // Let the derived class specify the gear ratios
    std::vector<double> fwd;
    double rev;
    SetGearRatios(fwd, rev);
    assert(fwd.size() > 0);
    if (rev > 0)
        rev *= -1;
    m_gear_ratios.push_back(rev);
    m_gear_ratios.insert(m_gear_ratios.end(), fwd.begin(), fwd.end());

    // Initialize the transmission in 1st gear
    SetGear(1);
}

void ChPowertrain::ShiftUp() {
    if (m_transmission_mode == TransmissionMode::MANUAL &&  //
        m_drive_mode == DriveMode::FORWARD &&               //
        m_current_gear < m_gear_ratios.size() - 1) {
        SetGear(m_current_gear + 1);
    }
}

void ChPowertrain::ShiftDown() {
    if (m_transmission_mode == TransmissionMode::MANUAL &&  //
        m_drive_mode == DriveMode::FORWARD &&               //
        m_current_gear > 1) {
        SetGear(m_current_gear - 1);
    }
}

void ChPowertrain::SetGear(int gear) {
    assert(gear >= 0);
    assert(gear < m_gear_ratios.size());

    m_current_gear = gear;
    m_current_gear_ratio = m_gear_ratios[m_current_gear];
    OnGearShift();
}

void ChPowertrain::SetDriveMode(DriveMode mode) {
    if (m_drive_mode == mode)
        return;

    m_drive_mode = mode;

    switch (m_drive_mode) {
        case DriveMode::FORWARD:
            SetGear(1);
            break;
        case DriveMode::NEUTRAL:
            m_current_gear_ratio = 1e20;
            OnNeutralShift();
            break;
        case DriveMode::REVERSE:
            SetGear(0);
            break;
    }
}

}  // end namespace vehicle
}  // end namespace chrono
<|endoftext|>


<commit_before>/* The MIT License (MIT)

Copyright (c) 2015 Gabriel Corona

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

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

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

#include "unjit.hpp"

#include <sys/uio.h>

#include <stdexcept>
#include <iostream>
#include <iomanip>

#include <llvm-c/Target.h>
#include <llvm-c/Disassembler.h>

// This is an adapter for the API expected by LLVMDisasmContextRef:
static const char* lookup_symbol(
  void *DisInfo,
  uint64_t ReferenceValue,
  uint64_t *ReferenceType,
  uint64_t ReferencePC,
  const char **ReferenceName)
{
  unjit::Process *process = (unjit::Process *) DisInfo;
  *ReferenceType = 0;
  *ReferenceName = NULL;
  return process->lookup_symbol(ReferenceValue);
}

namespace unjit
{

Disassembler::Disassembler(Process& process) : process_(&process)
{
  // Create and setup the disassembler:
  this->disassembler_ = LLVMCreateDisasmCPU(
    LLVM_HOST_TRIPLE, "core2",
    this->process_, 0, NULL, lookup_symbol);
  if (!this->disassembler_) {
    throw std::runtime_error("Could not intialize LLVM disassembler");
  }
  LLVMSetDisasmOptions(this->disassembler_,
    LLVMDisassembler_Option_SetInstrComments
    | LLVMDisassembler_Option_PrintLatency
    );
}

Disassembler::~Disassembler()
{
  LLVMDisasmDispose(this->disassembler_);
}

void Disassembler::disassemble_code(std::ostream& stream, uint8_t *code, std::uint64_t start, std::size_t size)
{
  std::uint64_t pc = start;
  char temp[256];
  while (size) {
    size_t c = LLVMDisasmInstruction(this->disassembler_,
      code, size, pc, temp, sizeof(temp));
    if (c == 0)
      return;
    stream << std::setfill('0') << std::setw(16) << std::hex << pc
      << ":\t" << temp << '\n';
    size -= c;
    code += c;
    pc += c;
  }
}

void Disassembler::disassemble(std::ostream& stream, const char* name, std::uint64_t start, std::uint64_t size)
{
  if (this->buffer_.size() < size)
    this->buffer_.resize(size);

  struct iovec local, remote;

  local.iov_base = this->buffer_.data();
  local.iov_len = size;

  remote.iov_base = (void*) start;
  remote.iov_len = size;

  if (process_vm_readv(this->process_->pid(), &local, 1, &remote, 1, 0) != size) {
    // TODO, return/throw error
    std::cerr << "Error, could not read the instructions for " << name << '\n';
    return;
  }

  stream << std::hex << start << '<' << name << ">\n";
  this->disassemble_code(stream, this->buffer_.data(), start, size);
  stream << '\n';
}

void Disassembler::disassemble(std::ostream& stream, std::uint64_t start, std::uint64_t size)
{
  const char* name = process_->lookup_symbol(start);
  disassemble(stream, name ? name : "_" , start, size);
}

}
<commit_msg>Small fix to the disassembly output<commit_after>/* The MIT License (MIT)

Copyright (c) 2015 Gabriel Corona

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

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

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

#include "unjit.hpp"

#include <sys/uio.h>

#include <stdexcept>
#include <iostream>
#include <iomanip>

#include <llvm-c/Target.h>
#include <llvm-c/Disassembler.h>

// This is an adapter for the API expected by LLVMDisasmContextRef:
static const char* lookup_symbol(
  void *DisInfo,
  uint64_t ReferenceValue,
  uint64_t *ReferenceType,
  uint64_t ReferencePC,
  const char **ReferenceName)
{
  unjit::Process *process = (unjit::Process *) DisInfo;
  *ReferenceType = 0;
  *ReferenceName = NULL;
  return process->lookup_symbol(ReferenceValue);
}

namespace unjit
{

Disassembler::Disassembler(Process& process) : process_(&process)
{
  // Create and setup the disassembler:
  this->disassembler_ = LLVMCreateDisasmCPU(
    LLVM_HOST_TRIPLE, "core2",
    this->process_, 0, NULL, lookup_symbol);
  if (!this->disassembler_) {
    throw std::runtime_error("Could not intialize LLVM disassembler");
  }
  LLVMSetDisasmOptions(this->disassembler_,
    LLVMDisassembler_Option_SetInstrComments
    | LLVMDisassembler_Option_PrintLatency
    );
}

Disassembler::~Disassembler()
{
  LLVMDisasmDispose(this->disassembler_);
}

void Disassembler::disassemble_code(std::ostream& stream, uint8_t *code, std::uint64_t start, std::size_t size)
{
  std::uint64_t pc = start;
  char temp[256];
  while (size) {
    size_t c = LLVMDisasmInstruction(this->disassembler_,
      code, size, pc, temp, sizeof(temp));
    if (c == 0)
      return;
    stream << std::setfill('0') << std::setw(16) << std::hex << pc
      << ":\t" << temp << '\n';
    size -= c;
    code += c;
    pc += c;
  }
}

void Disassembler::disassemble(std::ostream& stream, const char* name, std::uint64_t start, std::uint64_t size)
{
  if (this->buffer_.size() < size)
    this->buffer_.resize(size);

  struct iovec local, remote;

  local.iov_base = this->buffer_.data();
  local.iov_len = size;

  remote.iov_base = (void*) start;
  remote.iov_len = size;

  if (process_vm_readv(this->process_->pid(), &local, 1, &remote, 1, 0) != size) {
    // TODO, return/throw error
    std::cerr << "Error, could not read the instructions for " << name << '\n';
    return;
  }

  stream << std::hex << start << " <" << name << ">\n";
  this->disassemble_code(stream, this->buffer_.data(), start, size);
  stream << '\n';
}

void Disassembler::disassemble(std::ostream& stream, std::uint64_t start, std::uint64_t size)
{
  const char* name = process_->lookup_symbol(start);
  disassemble(stream, name ? name : "_" , start, size);
}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

#include "using.h"
#include "foobar.h"

template<typename T>
class Property : public using_<Property<T>, T>
{
public:
    operator T &()
    {
        return data;
    }

private:
    T data;
};

int main()
{
    std::cout << "Hello, Wandbox!" << std::endl;

    Property<std::vector<int>> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    //v.push_back(1, 2, 3);

    for (auto x : v)
    {
        std::cout << x << std::endl;
    }

    Property<int> x{};
    Property<int> y{};

    auto z = x + y;

    std::cout << z << std::endl;
    std::cout << typeid(z).name() << std::endl;

    Property<Foo> foo;
    foo.foo();
}
<commit_msg>Introduced using_ into scope<commit_after>#include <iostream>
#include <vector>

#include "using.h"
#include "foobar.h"

using delegate_using::using_;

template<typename T>
class Property : public using_<Property<T>, T>
{
public:
    operator T &()
    {
        return data;
    }

private:
    T data;
};

int main()
{
    std::cout << "Hello, Wandbox!" << std::endl;

    Property<std::vector<int>> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    //v.push_back(1, 2, 3);

    for (auto x : v)
    {
        std::cout << x << std::endl;
    }

    Property<int> x{};
    Property<int> y{};

    auto z = x + y;

    std::cout << z << std::endl;
    std::cout << typeid(z).name() << std::endl;

    Property<Foo> foo;
    foo.foo();
}
<|endoftext|>


<commit_before>#include "luaobj/Luaobj.h"

#include "gtest/gtest.h"

LuaAutoState *L=NULL;

TEST(LuaObj,TestInit)
{
	ASSERT_EQ(L,LuaAutoState::current())<<"register current thread faield";
	ASSERT_EQ(L->getTop(),0);

	{
		LuaObject obj(L);
		ASSERT_EQ(L->getTop(),1);
	}
	ASSERT_EQ(L->getTop(),0);

	{
		LuaObject * obj1=new LuaObject(L);
		LuaObject * obj2=new LuaObject(L);
		LuaObject * obj3=new LuaObject(L);

		delete obj2;
		delete obj1;
		delete obj3;

	}
	ASSERT_EQ(L->getTop(),0);
}

TEST(LuaObj,TestValue)
{
	LuaObject nil=L->newNil();
	EXPECT_TRUE(nil.isNil());

	for (lua_Number num=-10.0;num<10.0;++num)
	{
		LuaObject lnumber=L->newNumber(num);
		EXPECT_TRUE(num==lnumber.toNumber());
	}

	for (lua_Integer num=-10;num<10;++num)
	{
		LuaObject lnumber=L->newInt(num);
		EXPECT_TRUE(num==lnumber.toInt());
	}

	LuaObject ltrue=L->newBool(true);
	EXPECT_TRUE(true==ltrue.toBool());

	LuaObject lfalse=L->newBool(false);
	EXPECT_TRUE(false==lfalse.toBool());

	int data=0x2312321;
	LuaObject ldata=L->newData(&data,sizeof(data));
	EXPECT_TRUE(data==*(int*)ldata.toData() && ldata.objLen()==sizeof(data));

	void *p=(void*)0x32432;
	LuaObject lptr=L->newPtr(p);
	EXPECT_TRUE(p==lptr.toData());

	const char* str="hello world";
	LuaObject lstr=L->newString(str);
	EXPECT_TRUE(strcmp(lstr.toString(),str)==0);
}

TEST(LuaObj,TestGlobalValue)
{
	const char* str="hello world";
	L->setGlobal("testGlobal.test",L->newString(str));
	LuaObject lstr=L->getGlobal("testGlobal.test");

	EXPECT_TRUE(strcmp(lstr.toString(),str)==0);
}

int CppAddFunction (LuaFuncState& L)
{
	return L.lreturn(L.arg(0).toInt()+L.arg(1).toInt());
}

TEST(LuaObj,TestCallFunction)
{
	LuaFunction lAddFunc=L->newFunction(CppAddFunction);

	EXPECT_EQ(lAddFunc(1,2).toInt(),3);
	EXPECT_EQ(lAddFunc(1000,2000).toInt(),3000);
	EXPECT_EQ(lAddFunc(-100,200).toInt(),100);
}

TEST(LuaObj,TestCallLuaFunction)
{
	const char* luaScript="function add(a,b) return a+b end";
	L->doString(luaScript);

	LuaFunction lAddFunc=L->getGlobal("add");

	EXPECT_EQ(lAddFunc(1,2).toInt(),3);
	EXPECT_EQ(lAddFunc(1000,2000).toInt(),3000);
	EXPECT_EQ(lAddFunc(-100,200).toInt(),100);
}

int addToCount=1000000;

TEST(LuaObj,TestLuaPerformance)
{

	try{
		const char* luaScript="function addTo(num)local all=0;for i=1,num do all=all+i; end\nreturn all;end";
		L->doString(luaScript);

		LuaFunction lAddToFunc=L->getGlobal("addTo");

		LuaObject value=lAddToFunc(addToCount);
		lua_Integer i=value.toInt();
		printf("luaAddTo %d value %d\n",addToCount,i);
	}
	catch(LuaException e)
	{
		printf("%s",e.what());
	}

}

TEST(LuaObj,TestCppPerformance)
{
	int all=0;
	for (int i=1;i<=addToCount;++i)
	{
		all+=i;
	}

	printf("CppAddTo %d value %d\n",addToCount,all);
}

TEST(LuaObj,TestGetField)
{
	L->doString("a={b={c=123}}");

	LuaObject obj=L->getField("a.b.c");
	EXPECT_EQ(obj.toInt(),123);
}

class Test
{
public:
	Test(int i)
	{

	}
	void test(const char* test)
	{
		printf(test);
	}
};

class Test2:public Test
{
public:
	Test2(LuaFuncState& L)
		:Test(L.arg(0).toInt())
	{
	}

	int test(LuaFuncState& L)
	{
		Test::test(L.arg(0).toString());
		return 0;
	}

	BEGIN_MAP_FUNC(Test2)
		DECLARE_METHOD(test),
	END_MAP_FUNC
};

int main(int argc, char **argv)
{
	LuaAutoState luaEngine;
	L=&luaEngine;

	testing::InitGoogleTest(&argc, argv);
	int rtn= RUN_ALL_TESTS();

	LuaClass<Test2>::Register(L->getLuaState(),NULL);

	L->doString("local test=Test2.new();test:test('test')");
	getchar();
	return rtn;
}

<commit_msg>add register test<commit_after>#include "luaobj/Luaobj.h"

#include "gtest/gtest.h"

LuaAutoState *L=NULL;

TEST(LuaObj,TestInit)
{
	ASSERT_EQ(L,LuaAutoState::current())<<"register current thread faield";
	ASSERT_EQ(L->getTop(),0);

	{
		LuaObject obj(L);
		ASSERT_EQ(L->getTop(),1);
	}
	ASSERT_EQ(L->getTop(),0);

	{
		LuaObject * obj1=new LuaObject(L);
		LuaObject * obj2=new LuaObject(L);
		LuaObject * obj3=new LuaObject(L);

		delete obj2;
		delete obj1;
		delete obj3;

	}
	ASSERT_EQ(L->getTop(),0);
}

TEST(LuaObj,TestValue)
{
	LuaObject nil=L->newNil();
	EXPECT_TRUE(nil.isNil());

	for (lua_Number num=-10.0;num<10.0;++num)
	{
		LuaObject lnumber=L->newNumber(num);
		EXPECT_TRUE(num==lnumber.toNumber());
	}

	for (lua_Integer num=-10;num<10;++num)
	{
		LuaObject lnumber=L->newInt(num);
		EXPECT_TRUE(num==lnumber.toInt());
	}

	LuaObject ltrue=L->newBool(true);
	EXPECT_TRUE(true==ltrue.toBool());

	LuaObject lfalse=L->newBool(false);
	EXPECT_TRUE(false==lfalse.toBool());

	int data=0x2312321;
	LuaObject ldata=L->newData(&data,sizeof(data));
	EXPECT_TRUE(data==*(int*)ldata.toData() && ldata.objLen()==sizeof(data));

	void *p=(void*)0x32432;
	LuaObject lptr=L->newPtr(p);
	EXPECT_TRUE(p==lptr.toData());

	const char* str="hello world";
	LuaObject lstr=L->newString(str);
	EXPECT_TRUE(strcmp(lstr.toString(),str)==0);
}

TEST(LuaObj,TestGlobalValue)
{
	const char* str="hello world";
	L->setGlobal("testGlobal.test",L->newString(str));
	LuaObject lstr=L->getGlobal("testGlobal.test");

	EXPECT_TRUE(strcmp(lstr.toString(),str)==0);
}

int CppAddFunction (LuaFuncState& L)
{
	return L.lreturn(L.arg(0).toInt()+L.arg(1).toInt());
}

TEST(LuaObj,TestCallFunction)
{
	LuaFunction lAddFunc=L->newFunction(CppAddFunction);

	EXPECT_EQ(lAddFunc(1,2).toInt(),3);
	EXPECT_EQ(lAddFunc(1000,2000).toInt(),3000);
	EXPECT_EQ(lAddFunc(-100,200).toInt(),100);
}

TEST(LuaObj,TestCallLuaFunction)
{
	const char* luaScript="function add(a,b) return a+b end";
	L->doString(luaScript);

	LuaFunction lAddFunc=L->getGlobal("add");

	EXPECT_EQ(lAddFunc(1,2).toInt(),3);
	EXPECT_EQ(lAddFunc(1000,2000).toInt(),3000);
	EXPECT_EQ(lAddFunc(-100,200).toInt(),100);
}

int addToCount=1000000;

TEST(LuaObj,TestLuaPerformance)
{

	try{
		const char* luaScript="function addTo(num)local all=0;for i=1,num do all=all+i; end\nreturn all;end";
		L->doString(luaScript);

		LuaFunction lAddToFunc=L->getGlobal("addTo");

		LuaObject value=lAddToFunc(addToCount);
		lua_Integer i=value.toInt();
		printf("luaAddTo %d value %d\n",addToCount,i);
	}
	catch(LuaException e)
	{
		printf("%s",e.what());
	}

}

TEST(LuaObj,TestCppPerformance)
{
	int all=0;
	for (int i=1;i<=addToCount;++i)
	{
		all+=i;
	}

	printf("CppAddTo %d value %d\n",addToCount,all);
}

TEST(LuaObj,TestGetField)
{
	L->doString("a={b={c=123}}");

	LuaObject obj=L->getField("a.b.c");
	EXPECT_EQ(obj.toInt(),123);
}

TEST(LuaObj,TestTableIterator)
{
	L->doString("a={1,2,3,4,a=5,b=6,c=7}");
	L->enumStack();
	LuaTable tab=L->getGlobal("a");
	for (LuaTable::Iterator i=tab.begin();i!=tab.end();++i)
	{
		printf("%d\t",i.value().toInt());
	}

	printf("\n");
	L->enumStack();
}

class Test
{
public:
	Test(int i)
	{

	}
	void test(const char* test)
	{
		printf("Test:%s\n",test);
	}
};

class Test2:public Test
{
public:
	Test2(LuaFuncState& L)
		:Test(L.arg(0).toInt())
	{
	}

	int test(LuaFuncState& L)
	{
		Test::test(L.arg(0).toString());
		return 0;
	}

	BEGIN_MAP_FUNC(Test2,"cc.Test")
		DECLARE_METHOD(test),
	END_MAP_FUNC
};

class Parent
{
public:
	void test(const char* test)
	{
		printf("Parent:%s\n",test);
	}
};

class Child:public Parent
{
public:
	void test(const char* test)
	{
		printf("Child:%s\n",test);
	}
};

class LParent:public Parent
{
public:
	LParent(LuaFuncState& L)
	{
	}
	int test(LuaFuncState& L)
	{
		Parent::test(L.arg(0).toString());
		return 0;
	}

	BEGIN_MAP_FUNC(LParent,"cc.Parent")
		DECLARE_METHOD(test),
	END_MAP_FUNC
};

class LChild:public Child
{
public:
	LChild(LuaFuncState& L)
	{
	}

	int test2(LuaFuncState& L)
	{
		Child::test(L.arg(0).toString());
		return 0;
	}

	BEGIN_MAP_FUNC(LChild,"cc.Child")
		DECLARE_METHOD(test2),
	END_MAP_FUNC
};

int main(int argc, char **argv)
{
	LuaAutoState luaEngine;
	L=&luaEngine;

	testing::InitGoogleTest(&argc, argv);
	int rtn= RUN_ALL_TESTS();

	LuaClass<Test2>::Register(L->getLuaState());
	LuaClass<LParent>::Register(L->getLuaState());
	LuaClass<LChild>::Register(L->getLuaState(),"cc.Parent");

	L->doString("local test=cc.Test.new();test:test('test')");
	L->doString("local test=cc.Parent.new();test:test('test')");
	L->doString("local test=cc.Child.new();test:test('test');test:test2('test')");
	getchar();
	return rtn;
}

<|endoftext|>


<commit_before>16fadf61-2748-11e6-9b2f-e0f84713e7b8<commit_msg>add file<commit_after>1704fca3-2748-11e6-8e61-e0f84713e7b8<|endoftext|>


<commit_before>#include <iostream>
#include <memory>
#include <fstream>

#include "Game/Game.h"
#include "Game/Board.h"

#include "Moves/Move.h"

#include "Players/Genetic_AI.h"
#include "Players/Human_Player.h"
#include "Players/Random_AI.h"
#include "Players/Outside_Player.h"

#include "Genes/Gene_Pool.h"

#include "Exceptions/Illegal_Move_Exception.h"
#include "Exceptions/Game_Ending_Exception.h"

#include "Utility.h"
#include "Testing.h"

void print_help();

int main(int argc, char *argv[])
{
    try
    {
        run_tests();

        if(argc > 1)
        {
            if(std::string(argv[1]) == "-genepool")
            {
                std::string gene_pool_config_file_name;
                if(argc > 2)
                {
                    gene_pool_config_file_name = argv[2];
                }

                gene_pool(gene_pool_config_file_name);
            }
            else if(std::string(argv[1]) == "-replay")
            {
                if(argc > 2)
                {
                    Board board;
                    std::string file_name = argv[2];
                    std::ifstream ifs(file_name);
                    std::string line;
                    bool game_started = false;
                    while( ! board.game_has_ended() && std::getline(ifs, line))
                    {
                        line = String::trim_outer_whitespace(line);
                        line = String::strip_block_comment(line, '{', '}');
                        line = String::strip_comments(line, ';');
                        if(line.empty())
                        {
                            if(game_started)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        if(line[0] == '[')
                        {
                            std::cout << line << std::endl;
                            continue;
                        }

                        for(const auto& s : String::split(line))
                        {
                            try
                            {
                                board.submit_move(board.get_complete_move(s));
                            }
                            catch(const Illegal_Move_Exception&)
                            {
                                std::cout << "Ignoring: " << s << std::endl;
                                continue;
                            }
                            catch(const Game_Ending_Exception& e)
                            {
                                std::cout << e.what() << std::endl;
                            }
                            board.ascii_draw(WHITE);
                            game_started = true;
                            std::cout << "Last move: ";
                            std::cout << (board.get_game_record().size() + 1)/2 << ". ";
                            std::cout << (board.whose_turn() == WHITE ? "... " : "");
                            std::cout << board.get_game_record().back() << std::endl;
                            if(board.game_has_ended())
                            {
                                break;
                            }

                            std::cout << "Enter \"y\" to play game from here: " << std::endl;
                            char response = std::cin.get();
                            if(std::tolower(response) == 'y')
                            {
                                play_game_with_board(Human_Player(),
                                                     Human_Player(),
                                                     0,
                                                     0,
                                                     0,
                                                     file_name + "_continued.pgn",
                                                     board);
                                 break;
                            }
                        }
                    }
                }
                else
                {
                    std::cerr << "-replay must be followed by a file name." << std::endl;
                    return 1;
                }
            }
            else
            {
                std::unique_ptr<Player> white;
                std::unique_ptr<Player> black;
                std::unique_ptr<Player> latest;

                int game_time = 0;
                int moves_per_reset = 0;
                int increment_time = 0;

                for(int i = 1; i < argc; ++i)
                {
                    std::string opt = argv[i];
                    if(opt == "-human")
                    {
                        latest.reset(new Human_Player());
                    }
                    else if(opt == "-random")
                    {
                        latest.reset(new Random_AI());
                    }
                    else if(opt == "-genetic")
                    {
                        Genetic_AI *genetic_ptr = nullptr;
                        std::string filename;
                        int id = -1;
                        if(i + 1 < argc)
                        {
                            filename = argv[i+1];
                            if(filename.front() == '-')
                            {
                                filename.clear();
                            }
                        }

                        if(i + 2 < argc)
                        {
                            try
                            {
                                id = std::stoi(argv[i+2]);
                            }
                            catch(const std::exception&)
                            {
                            }
                        }

                        if(filename.empty())
                        {
                            genetic_ptr = new Genetic_AI;
                            for(int j = 0; j < 100; ++j)
                            {
                                genetic_ptr->mutate();
                            }
                            genetic_ptr->print_genome("single_game_player.txt");
                        }
                        else
                        {
                            if(id < 0)
                            {
                                genetic_ptr = new Genetic_AI(filename);
                                i += 1;
                            }
                            else
                            {
                                genetic_ptr = new Genetic_AI(filename, id);
                                i += 2;
                            }
                        }

                        latest.reset(genetic_ptr);
                    }
                    else if(opt == "-time")
                    {
                        game_time = std::stoi(argv[++i]);
                    }
                    else if(opt == "-reset_moves")
                    {
                        moves_per_reset = std::stoi(argv[++i]);
                    }
                    else if(opt == "-increment_time")
                    {
                        increment_time = std::stoi(argv[++i]);
                    }
                    else
                    {
                        throw std::runtime_error("Invalid option: " + opt);
                    }

                    if(latest)
                    {
                        if( ! white)
                        {
                            white = std::move(latest);
                            continue;
                        }
                        if( ! black)
                        {
                            black = std::move(latest);
                            continue;
                        }
                    }
                }

                std::string game_file_name = "game.pgn";

                if(black)
                {
                    play_game(*white, *black, game_time, moves_per_reset, increment_time, game_file_name);
                }
                else
                {
                    auto outside = connect_to_outside();
                    game_time = outside->get_game_time();
                    moves_per_reset = outside->get_reset_moves();
                    increment_time = outside->get_increment();

                    if(outside->get_ai_color() == WHITE)
                    {
                        play_game(*white, *outside, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                    else
                    {
                        play_game(*outside, *white, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                }
            }
        }
        else
        {
            print_help();
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << "\n\nERROR: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

void print_help()
{
    std::cout << "\n\nGenetic Chess" << std::endl
              << "=============" << std::endl << std::endl
              << "Options:" << std::endl
              << "\t-genepool [file name]" << std::endl
              << "\t\tStart a run of a gene pool with parameters set in the given\n\t\tfile name." << std::endl << std::endl
              << "\t-replay [filename]" << std::endl
              << "\t\tStep through a PGN game file, drawing the board after each\n\t\tmove with an option to begin playing at any time." << std::endl << std::endl
              << "The following options start a game with various players. If two players are\nspecified, the first plays white and the second black. If only one player is\nspecified, the program will wait for a CECP command from outside to start\nplaying." << std::endl << std::endl
              << "\t-human" << std::endl
              << "\t\tSpecify a human player for a game." << std::endl << std::endl
              << "\t-genetic [filename [number]]" << std::endl
              << "\t\tSpecify a genetic AI player for a game. Optional file name and\n\t\tID number to load an AI from a file." << std::endl << std::endl
              << "\t-random" << std::endl
              << "\t\tSpecify a player that makes random moves for a game." << std::endl << std::endl
              << "\t-time [number]" << std::endl
              << "\t\tSpecify the time each player has to play the game or to make\n\t\ta set number of moves (see -reset_moves option)." << std::endl << std::endl
              << "\t-reset_moves [number]" << std::endl
              << "\t\tSpecify the number of moves a player must make within the time\n\t\tlimit. The clock resets to the initial time every time this\n\t\tnumber of moves is made." << std::endl << std::endl
              << "\t-increment_time [number]" << std::endl
              << "\t\tSpecify seconds to add to time after each move." << std::endl << std::endl;
}
<commit_msg>Load last Genetic AI in file by default<commit_after>#include <iostream>
#include <memory>
#include <fstream>

#include "Game/Game.h"
#include "Game/Board.h"

#include "Moves/Move.h"

#include "Players/Genetic_AI.h"
#include "Players/Human_Player.h"
#include "Players/Random_AI.h"
#include "Players/Outside_Player.h"

#include "Genes/Gene_Pool.h"

#include "Exceptions/Illegal_Move_Exception.h"
#include "Exceptions/Game_Ending_Exception.h"

#include "Utility.h"
#include "Testing.h"

void print_help();
int find_last_id(const std::string& filename);

int main(int argc, char *argv[])
{
    try
    {
        run_tests();

        if(argc > 1)
        {
            if(std::string(argv[1]) == "-genepool")
            {
                std::string gene_pool_config_file_name;
                if(argc > 2)
                {
                    gene_pool_config_file_name = argv[2];
                }

                gene_pool(gene_pool_config_file_name);
            }
            else if(std::string(argv[1]) == "-replay")
            {
                if(argc > 2)
                {
                    Board board;
                    std::string file_name = argv[2];
                    std::ifstream ifs(file_name);
                    std::string line;
                    bool game_started = false;
                    while( ! board.game_has_ended() && std::getline(ifs, line))
                    {
                        line = String::trim_outer_whitespace(line);
                        line = String::strip_block_comment(line, '{', '}');
                        line = String::strip_comments(line, ';');
                        if(line.empty())
                        {
                            if(game_started)
                            {
                                break;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        if(line[0] == '[')
                        {
                            std::cout << line << std::endl;
                            continue;
                        }

                        for(const auto& s : String::split(line))
                        {
                            try
                            {
                                board.submit_move(board.get_complete_move(s));
                            }
                            catch(const Illegal_Move_Exception&)
                            {
                                std::cout << "Ignoring: " << s << std::endl;
                                continue;
                            }
                            catch(const Game_Ending_Exception& e)
                            {
                                std::cout << e.what() << std::endl;
                            }
                            board.ascii_draw(WHITE);
                            game_started = true;
                            std::cout << "Last move: ";
                            std::cout << (board.get_game_record().size() + 1)/2 << ". ";
                            std::cout << (board.whose_turn() == WHITE ? "... " : "");
                            std::cout << board.get_game_record().back() << std::endl;
                            if(board.game_has_ended())
                            {
                                break;
                            }

                            std::cout << "Enter \"y\" to play game from here: " << std::endl;
                            char response = std::cin.get();
                            if(std::tolower(response) == 'y')
                            {
                                play_game_with_board(Human_Player(),
                                                     Human_Player(),
                                                     0,
                                                     0,
                                                     0,
                                                     file_name + "_continued.pgn",
                                                     board);
                                 break;
                            }
                        }
                    }
                }
                else
                {
                    std::cerr << "-replay must be followed by a file name." << std::endl;
                    return 1;
                }
            }
            else
            {
                std::unique_ptr<Player> white;
                std::unique_ptr<Player> black;
                std::unique_ptr<Player> latest;

                int game_time = 0;
                int moves_per_reset = 0;
                int increment_time = 0;

                for(int i = 1; i < argc; ++i)
                {
                    std::string opt = argv[i];
                    if(opt == "-human")
                    {
                        latest.reset(new Human_Player());
                    }
                    else if(opt == "-random")
                    {
                        latest.reset(new Random_AI());
                    }
                    else if(opt == "-genetic")
                    {
                        Genetic_AI *genetic_ptr = nullptr;
                        std::string filename;
                        int id = -1;
                        if(i + 1 < argc)
                        {
                            filename = argv[i+1];
                            if(filename.front() == '-')
                            {
                                filename.clear();
                            }
                        }

                        if(i + 2 < argc)
                        {
                            try
                            {
                                id = std::stoi(argv[i+2]);
                            }
                            catch(const std::exception&)
                            {
                            }
                        }

                        if(filename.empty())
                        {
                            genetic_ptr = new Genetic_AI;
                            for(int j = 0; j < 100; ++j)
                            {
                                genetic_ptr->mutate();
                            }
                            genetic_ptr->print_genome("single_game_player.txt");
                        }
                        else
                        {
                            if(id < 0)
                            {
                                genetic_ptr = new Genetic_AI(filename, find_last_id(filename));
                                i += 1;
                            }
                            else
                            {
                                genetic_ptr = new Genetic_AI(filename, id);
                                i += 2;
                            }
                        }

                        latest.reset(genetic_ptr);
                    }
                    else if(opt == "-time")
                    {
                        game_time = std::stoi(argv[++i]);
                    }
                    else if(opt == "-reset_moves")
                    {
                        moves_per_reset = std::stoi(argv[++i]);
                    }
                    else if(opt == "-increment_time")
                    {
                        increment_time = std::stoi(argv[++i]);
                    }
                    else
                    {
                        throw std::runtime_error("Invalid option: " + opt);
                    }

                    if(latest)
                    {
                        if( ! white)
                        {
                            white = std::move(latest);
                            continue;
                        }
                        if( ! black)
                        {
                            black = std::move(latest);
                            continue;
                        }
                    }
                }

                std::string game_file_name = "game.pgn";

                if(black)
                {
                    play_game(*white, *black, game_time, moves_per_reset, increment_time, game_file_name);
                }
                else
                {
                    auto outside = connect_to_outside();
                    game_time = outside->get_game_time();
                    moves_per_reset = outside->get_reset_moves();
                    increment_time = outside->get_increment();

                    if(outside->get_ai_color() == WHITE)
                    {
                        play_game(*white, *outside, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                    else
                    {
                        play_game(*outside, *white, game_time, moves_per_reset, increment_time, game_file_name);
                    }
                }
            }
        }
        else
        {
            print_help();
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << "\n\nERROR: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

void print_help()
{
    std::cout << "\n\nGenetic Chess" << std::endl
              << "=============" << std::endl << std::endl
              << "Options:" << std::endl
              << "\t-genepool [file name]" << std::endl
              << "\t\tStart a run of a gene pool with parameters set in the given\n\t\tfile name." << std::endl << std::endl
              << "\t-replay [filename]" << std::endl
              << "\t\tStep through a PGN game file, drawing the board after each\n\t\tmove with an option to begin playing at any time." << std::endl << std::endl
              << "The following options start a game with various players. If two players are\nspecified, the first plays white and the second black. If only one player is\nspecified, the program will wait for a CECP command from outside to start\nplaying." << std::endl << std::endl
              << "\t-human" << std::endl
              << "\t\tSpecify a human player for a game." << std::endl << std::endl
              << "\t-genetic [filename [number]]" << std::endl
              << "\t\tSpecify a genetic AI player for a game. Optional file name and\n\t\tID number to load an AI from a file." << std::endl << std::endl
              << "\t-random" << std::endl
              << "\t\tSpecify a player that makes random moves for a game." << std::endl << std::endl
              << "\t-time [number]" << std::endl
              << "\t\tSpecify the time each player has to play the game or to make\n\t\ta set number of moves (see -reset_moves option)." << std::endl << std::endl
              << "\t-reset_moves [number]" << std::endl
              << "\t\tSpecify the number of moves a player must make within the time\n\t\tlimit. The clock resets to the initial time every time this\n\t\tnumber of moves is made." << std::endl << std::endl
              << "\t-increment_time [number]" << std::endl
              << "\t\tSpecify seconds to add to time after each move." << std::endl << std::endl;
}

int find_last_id(const std::string& filename)
{
    std::ifstream ifs(filename);
    std::string line;
    std::string id_line;
    while(std::getline(ifs, line))
    {
        if(String::starts_with(line, "ID:"))
        {
            id_line = line;
        }
    }

    if(id_line.empty())
    {
        throw std::runtime_error("No Genetic AIs found in " + filename);
    }
    else
    {
        return std::stoi(String::split(id_line)[1]);
    }
}
<|endoftext|>


<commit_before>cb062585-ad5a-11e7-8912-ac87a332f658<commit_msg>Fix that bug where things didn't work but now they should<commit_after>cbb1c9fd-ad5a-11e7-b748-ac87a332f658<|endoftext|>


<commit_before>#include <GLXW/glxw.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include <defer.h>
#include <chrono>

#define STBI_NO_GIF 1
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"

#include "utils/utils.h"
#include "utils/camera.h"

static const GLfloat globVertexBufferData[] = {
//   X     Y     Z       U     V
// front
     1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
// front, |_ part
    -1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,   0.0f, 0.0f,
     1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
// left, _| part
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
// left
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
// back
     1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
// back, |_ part
     1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
     1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
// right
     1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
     1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
// right, |_ part
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
     1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f, 1.0f,   0.0f, 0.0f,
// top
     1.0f, 1.0f, 1.0f,   1.0f, 0.0f,
     1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
// top, |_ part
     1.0f, 1.0f, 1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,   0.0f, 0.0f,
// bottom, _| part
     1.0f,-1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
// bottom
     1.0f,-1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
};

void windowSizeCallback(GLFWwindow *, int width, int height) {
  glViewport(0, 0, width, height);
}

int main() {
  if(glfwInit() == GL_FALSE) {
    std::cerr << "Failed to initialize GLFW" << std::endl;
    return -1;
  }
  defer(std::cout << "Calling glfwTerminate()" << std::endl; glfwTerminate());

  glfwDefaultWindowHints();

  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

  GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating box", nullptr, nullptr);
  if(window == nullptr) {
    std::cerr << "Failed to open GLFW window" << std::endl;
    return -1;
  }
  defer(std::cout << "Calling glfwDestroyWindow()" << std::endl; glfwDestroyWindow(window));

  glfwMakeContextCurrent(window);

  if(glxwInit()) {
    std::cerr << "Failed to init GLXW" << std::endl;
    return -1;
  }

  glfwSwapInterval(1);

  glfwSetWindowSizeCallback(window, windowSizeCallback);

  glfwShowWindow(window);

  bool errorFlag = false;
  std::vector<GLuint> shaders;

  GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl;
    return -1;
  }

  shaders.push_back(vertexShaderId);

  GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl;
    return -1;
  }
  shaders.push_back(fragmentShaderId);

  GLuint programId = prepareProgram(shaders, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to prepare program" << std::endl;
    return -1;
  }
  defer(glDeleteProgram(programId));

  glDeleteShader(vertexShaderId);
  glDeleteShader(fragmentShaderId);

  GLuint vertexVBO;
  glGenBuffers(1, &vertexVBO);
  defer(glDeleteBuffers(1, &vertexVBO));

  glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(globVertexBufferData), globVertexBufferData, GL_STATIC_DRAW);

  // Create one OpenGL texture
  GLuint texture;
  glGenTextures(1, &texture);
  defer(glDeleteTextures(1, &texture));

// "Bind" the newly created texture : all future texture functions will modify this texture
  glBindTexture(GL_TEXTURE_2D, texture);

  // TODO: change box-debug.jpg to box.jpg
  int width, height, n;
  unsigned char *textureData = stbi_load("textures/box.jpg", &width, &height, &n, 0);
  flipTexture(textureData, width, height, n);

  if(textureData == nullptr) {
    std::cout << "Failed to load a texture!" << std::endl;
    return -1;
  }
  defer(stbi_image_free(textureData));

  // Give the image to OpenGL
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

  // Generate mipmaps
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glGenerateMipmap(GL_TEXTURE_2D);

  glBindTexture(GL_TEXTURE_2D, 0); // unbind

  GLuint vao;
  glGenVertexArrays(1, &vao);
  defer(glDeleteVertexArrays(1, &vao));

  glBindVertexArray(vao);

  glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), nullptr);
  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (const void*)(3*sizeof(GLfloat)));
  glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO

  glBindVertexArray(0); // unbind VAO

  glm::mat4 projection = glm::perspective(80.0f, 4.0f / 3.0f, 0.3f, 100.0f);

  GLint matrixId = glGetUniformLocation(programId, "MVP");
  GLint textureId = glGetUniformLocation(programId, "textureSampler");

  auto startTime = std::chrono::high_resolution_clock::now();
  auto prevTime = startTime;

  // hide cursor
  glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

  Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */);

  glEnable(GL_DOUBLEBUFFER);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
  glDepthFunc(GL_LESS);

  glClearColor(0, 0, 0, 1);

  while(glfwWindowShouldClose(window) == GL_FALSE) {
    if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break;

    if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    auto currentTime = std::chrono::high_resolution_clock::now();
    float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count();
    float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count();
    prevTime = currentTime;

    float rotationTimeMs = 3000.0f;
    float currentRotation = startDeltaTimeMs / rotationTimeMs;
    float angle = 360.0f*(currentRotation - (long)currentRotation);

    glm::mat4 view;
    camera.getViewMatrix(prevDeltaTimeMs, &view);

    glm::mat4 model = glm::rotate(angle, 0.0f, 1.0f, 0.0f);
    glm::mat4 mvp = projection * view * model; // matrix multiplication is the other way around
    glUniformMatrix4fv(matrixId, 1, GL_FALSE, &mvp[0][0]);

    // Bind our texture in Texture Unit 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    // Set our "textureSampler" sampler to user Texture Unit 0
    glUniform1i(textureId, 0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programId);

    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLES, 0, 3*12);
    glEnableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  return 0;
}
<commit_msg>Minor changes<commit_after>#include <GLXW/glxw.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include <defer.h>
#include <chrono>

#define STBI_NO_GIF 1
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"

#include "utils/utils.h"
#include "utils/camera.h"

static const GLfloat globVertexBufferData[] = {
//   X     Y     Z       U     V
// front
     1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
// front, |_ part
    -1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,   0.0f, 0.0f,
     1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
// left, _| part
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f,-1.0f, 1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
// left
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f, 1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
// back
     1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
// back, |_ part
     1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
     1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
    -1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
// right
     1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
     1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
// right, |_ part
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
     1.0f, 1.0f, 1.0f,   0.0f, 1.0f,
     1.0f,-1.0f, 1.0f,   0.0f, 0.0f,
// top
     1.0f, 1.0f, 1.0f,   1.0f, 0.0f,
     1.0f, 1.0f,-1.0f,   1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
// top, |_ part
     1.0f, 1.0f, 1.0f,   1.0f, 0.0f,
    -1.0f, 1.0f,-1.0f,   0.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,   0.0f, 0.0f,
// bottom, _| part
     1.0f,-1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
     1.0f,-1.0f,-1.0f,   1.0f, 0.0f,
// bottom
     1.0f,-1.0f, 1.0f,   1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,   0.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,   0.0f, 0.0f,
};

void windowSizeCallback(GLFWwindow *, int width, int height) {
  glViewport(0, 0, width, height);
}

int main() {
  if(glfwInit() == GL_FALSE) {
    std::cerr << "Failed to initialize GLFW" << std::endl;
    return -1;
  }
  defer(std::cout << "Calling glfwTerminate()" << std::endl; glfwTerminate());

  glfwDefaultWindowHints();

  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

  GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating box", nullptr, nullptr);
  if(window == nullptr) {
    std::cerr << "Failed to open GLFW window" << std::endl;
    return -1;
  }
  defer(std::cout << "Calling glfwDestroyWindow()" << std::endl; glfwDestroyWindow(window));

  glfwMakeContextCurrent(window);

  if(glxwInit()) {
    std::cerr << "Failed to init GLXW" << std::endl;
    return -1;
  }

  glfwSwapInterval(1);

  glfwSetWindowSizeCallback(window, windowSizeCallback);

  glfwShowWindow(window);

  bool errorFlag = false;
  std::vector<GLuint> shaders;

  GLuint vertexShaderId = loadShader("shaders/vertexShader.glsl", GL_VERTEX_SHADER, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to load vertex shader (invalid working directory?)" << std::endl;
    return -1;
  }

  shaders.push_back(vertexShaderId);

  GLuint fragmentShaderId = loadShader("shaders/fragmentShader.glsl", GL_FRAGMENT_SHADER, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to load fragment shader (invalid working directory?)" << std::endl;
    return -1;
  }
  shaders.push_back(fragmentShaderId);

  GLuint programId = prepareProgram(shaders, &errorFlag);
  if(errorFlag) {
    std::cerr << "Failed to prepare program" << std::endl;
    return -1;
  }
  defer(glDeleteProgram(programId));

  glDeleteShader(vertexShaderId);
  glDeleteShader(fragmentShaderId);

  GLuint vertexVBO;
  glGenBuffers(1, &vertexVBO);
  defer(glDeleteBuffers(1, &vertexVBO));

  glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(globVertexBufferData), globVertexBufferData, GL_STATIC_DRAW);

  // Load texture data
  int width, height, n;
  unsigned char *textureData = stbi_load("textures/box.jpg", &width, &height, &n, 0);
  flipTexture(textureData, width, height, n);

  if(textureData == nullptr) {
    std::cout << "Failed to load a texture!" << std::endl;
    return -1;
  }
  defer(stbi_image_free(textureData));

  // Create an OpenGL texture
  GLuint texture;
  glGenTextures(1, &texture);
  defer(glDeleteTextures(1, &texture));

  glBindTexture(GL_TEXTURE_2D, texture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

  // Generate mipmaps
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glGenerateMipmap(GL_TEXTURE_2D);

  glBindTexture(GL_TEXTURE_2D, 0); // unbind

  GLuint vao;
  glGenVertexArrays(1, &vao);
  defer(glDeleteVertexArrays(1, &vao));

  glBindVertexArray(vao);

  glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), nullptr);
  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (const void*)(3*sizeof(GLfloat)));
  glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind VBO

  glBindVertexArray(0); // unbind VAO

  glm::mat4 projection = glm::perspective(80.0f, 4.0f / 3.0f, 0.3f, 100.0f);

  GLint matrixId = glGetUniformLocation(programId, "MVP");
  GLint textureId = glGetUniformLocation(programId, "textureSampler");

  auto startTime = std::chrono::high_resolution_clock::now();
  auto prevTime = startTime;

  // hide cursor
  glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

  Camera camera(window, glm::vec3(0, 0, 5), 3.14f /* toward -Z */, 0.0f /* look at the horizon */);

  glEnable(GL_DOUBLEBUFFER);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
  glDepthFunc(GL_LESS);

  glClearColor(0, 0, 0, 1);

  while(glfwWindowShouldClose(window) == GL_FALSE) {
    if(glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) break;

    if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    auto currentTime = std::chrono::high_resolution_clock::now();
    float startDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count();
    float prevDeltaTimeMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - prevTime).count();
    prevTime = currentTime;

    float rotationTimeMs = 3000.0f;
    float currentRotation = startDeltaTimeMs / rotationTimeMs;
    float angle = 360.0f*(currentRotation - (long)currentRotation);

    glm::mat4 view;
    camera.getViewMatrix(prevDeltaTimeMs, &view);

    glm::mat4 model = glm::rotate(angle, 0.0f, 1.0f, 0.0f);
    glm::mat4 mvp = projection * view * model; // matrix multiplication is the other way around
    glUniformMatrix4fv(matrixId, 1, GL_FALSE, &mvp[0][0]);

    // Bind texture in texture unit 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    // Set "textureSampler"to texture unit 0
    glUniform1i(textureId, 0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programId);

    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLES, 0, 3*12);
    glEnableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  return 0;
}
<|endoftext|>


<commit_before>1148cfca-2748-11e6-9c4e-e0f84713e7b8<commit_msg>Adding stuff<commit_after>1157be2b-2748-11e6-ad0a-e0f84713e7b8<|endoftext|>


<commit_before>//! \file
//! Entry point

#include <SFML/Graphics.hpp>
#include "Game.h"
#include "SFAnimation.h"

int main()
{
    sf::RenderWindow window(sf::VideoMode(1280, 720), "My window");
	window.setFramerateLimit(60);
	sf::CircleShape shape(20.f);
	shape.setFillColor(sf::Color::Yellow);

	sf::Texture texture;
	if (!texture.loadFromFile("../pacman.png"))
	{
		return 1;
	}

	sf::Sprite sprite;
	sprite.setTexture(texture);
	sprite.setScale(sf::Vector2f(-2.0f, 2.0f));
	sprite.setOrigin(sf::Vector2f(16, 16));

	SFAnimation pac_move(4);
	pac_move.Frames.push_back(sf::IntRect(34, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(1, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(34, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(67, 170, 32, 32));
	int frame = 0;

	Field f;
	for (int i = 0; i < FIELD_WIDTH; i++)
	{
		for (int j = 0; j < FIELD_HEIGHT; j++)
		{
			if (i == 0 || i == FIELD_WIDTH - 1 || j == 0 || j == FIELD_HEIGHT - 1)
			{
				f.Tiles[i][j] = Field::Wall;
			}
			else
			{
				f.Tiles[i][j] = Field::Empty;
			}
		}
	}
	Game g(f, {{ Player(Player::Pacman) }});

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
			switch (event.type)
			{
				case sf::Event::KeyPressed:
					switch (event.key.code)
					{
						case sf::Keyboard::W:
							g.Players[0].NextDir = Player::Up;
							break;
						case sf::Keyboard::A:
							g.Players[0].NextDir = Player::Left;
							break;
						case sf::Keyboard::S:
							g.Players[0].NextDir = Player::Down;
							break;
						case sf::Keyboard::D:
							g.Players[0].NextDir = Player::Right;
							break;
					}
					break;
				case sf::Event::Closed:
					window.close();
					break;
			}
        }

		g.update();
		sprite.setTextureRect(pac_move.getRect(frame++));
		sprite.setPosition(g.Players[0].XPos * 8.f, g.Players[0].YPos * 8.f);
		sprite.setRotation(g.Players[0].CurrentDir * -90);
        window.clear();

		// draw
		window.draw(sprite);

        window.display();
    }

    return 0;
}
<commit_msg>Removed C++11 requirement<commit_after>//! \file
//! Entry point

#include <SFML/Graphics.hpp>
#include "Game.h"
#include "SFAnimation.h"

int main()
{
    sf::RenderWindow window(sf::VideoMode(1280, 720), "My window");
	window.setFramerateLimit(60);
	sf::CircleShape shape(20.f);
	shape.setFillColor(sf::Color::Yellow);

	sf::Texture texture;
	if (!texture.loadFromFile("../pacman.png"))
	{
		return 1;
	}

	sf::Sprite sprite;
	sprite.setTexture(texture);
	sprite.setScale(sf::Vector2f(-2.0f, 2.0f));
	sprite.setOrigin(sf::Vector2f(16, 16));

	SFAnimation pac_move(4);
	pac_move.Frames.push_back(sf::IntRect(34, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(1, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(34, 170, 32, 32));
	pac_move.Frames.push_back(sf::IntRect(67, 170, 32, 32));
	int frame = 0;

	Field f;
	for (int i = 0; i < FIELD_WIDTH; i++)
	{
		for (int j = 0; j < FIELD_HEIGHT; j++)
		{
			if (i == 0 || i == FIELD_WIDTH - 1 || j == 0 || j == FIELD_HEIGHT - 1)
			{
				f.Tiles[i][j] = Field::Wall;
			}
			else
			{
				f.Tiles[i][j] = Field::Empty;
			}
		}
	}
	std::vector<Player> p(1, Player(Player::Pacman));
	Game g(f, p);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
			switch (event.type)
			{
				case sf::Event::KeyPressed:
					switch (event.key.code)
					{
						case sf::Keyboard::W:
							g.Players[0].NextDir = Player::Up;
							break;
						case sf::Keyboard::A:
							g.Players[0].NextDir = Player::Left;
							break;
						case sf::Keyboard::S:
							g.Players[0].NextDir = Player::Down;
							break;
						case sf::Keyboard::D:
							g.Players[0].NextDir = Player::Right;
							break;
					}
					break;
				case sf::Event::Closed:
					window.close();
					break;
			}
        }

		g.update();
		sprite.setTextureRect(pac_move.getRect(frame++));
		sprite.setPosition(g.Players[0].XPos * 8.f, g.Players[0].YPos * 8.f);
		sprite.setRotation(g.Players[0].CurrentDir * -90);
        window.clear();

		// draw
		window.draw(sprite);

        window.display();
    }

    return 0;
}
<|endoftext|>