<commit_before>/* Copyright (c) 2018-present Advanced Micro Devices, Inc.

 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 <hip/hip_runtime.h>

#include "hip_internal.hpp"

namespace hip {

// ================================================================================================
amd::HostQueue* Device::NullStream(bool skip_alloc) {
  amd::HostQueue* null_queue = null_stream_.asHostQueue(skip_alloc);
  if (null_queue == nullptr) {
    return nullptr;
  }
  // Wait for all active streams before executing commands on the default
  iHipWaitActiveStreams(null_queue);
  return null_queue;
}

}

hipError_t hipDeviceGet(hipDevice_t *device, int deviceId) {
  HIP_INIT_API(hipDeviceGet, device, deviceId);

  if (device != nullptr) {
    *device = deviceId;
  } else {
    HIP_RETURN(hipErrorInvalidValue);
  }

  HIP_RETURN(hipSuccess);
};

hipError_t hipDeviceTotalMem (size_t *bytes, hipDevice_t device) {

  HIP_INIT_API(hipDeviceTotalMem, bytes, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (bytes == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();

  *bytes = info.globalMemSize_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device) {

  HIP_INIT_API(hipDeviceComputeCapability, major, minor, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (major == nullptr || minor == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  *major = info.gfxipMajor_;
  *minor = info.gfxipMinor_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceGetCount(int* count) {
  HIP_INIT_API(hipDeviceGetCount, count);

  HIP_RETURN(ihipDeviceGetCount(count));
}

hipError_t ihipDeviceGetCount(int* count) {
  if (count == nullptr) {
    return hipErrorInvalidValue;
  }

  // Get all available devices
  *count = g_devices.size();

  if (*count < 1) {
    return hipErrorNoDevice;
  }

  return hipSuccess;
}

hipError_t hipDeviceGetName(char *name, int len, hipDevice_t device) {

  HIP_INIT_API(hipDeviceGetName, (void*)name, len, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (name == nullptr || len <= 0) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  const auto nameLen = ::strlen(info.boardName_);

  // Make sure that the size of `dest` is big enough to hold `src` including
  // trailing zero byte
  if (nameLen > (cl_uint)(len - 1)) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  ::strncpy(name, info.boardName_, (nameLen + 1));

  HIP_RETURN(hipSuccess);
}

hipError_t hipGetDeviceProperties ( hipDeviceProp_t* props, hipDevice_t device ) {
  HIP_INIT_API(hipGetDeviceProperties, props, device);

  if (props == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  if (unsigned(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }
  auto* deviceHandle = g_devices[device]->devices()[0];

  hipDeviceProp_t deviceProps = {0};

  const auto& info = deviceHandle->info();
  ::strncpy(deviceProps.name, info.boardName_, 128);
  deviceProps.totalGlobalMem = info.globalMemSize_;
  deviceProps.sharedMemPerBlock = info.localMemSizePerCU_;
  deviceProps.regsPerBlock = info.availableRegistersPerCU_;
  deviceProps.warpSize = info.wavefrontWidth_;
  deviceProps.maxThreadsPerBlock = info.maxWorkGroupSize_;
  deviceProps.maxThreadsDim[0] = info.maxWorkItemSizes_[0];
  deviceProps.maxThreadsDim[1] = info.maxWorkItemSizes_[1];
  deviceProps.maxThreadsDim[2] = info.maxWorkItemSizes_[2];
  deviceProps.maxGridSize[0] = INT32_MAX;
  deviceProps.maxGridSize[1] = INT32_MAX;
  deviceProps.maxGridSize[2] = INT32_MAX;
  deviceProps.clockRate = info.maxEngineClockFrequency_ * 1000;
  deviceProps.memoryClockRate = info.maxMemoryClockFrequency_ * 1000;
  deviceProps.memoryBusWidth = info.globalMemChannels_;
  deviceProps.totalConstMem = info.maxConstantBufferSize_;
  deviceProps.major = info.gfxipMajor_;
  deviceProps.minor = info.gfxipMinor_;
  deviceProps.multiProcessorCount = info.maxComputeUnits_;
  deviceProps.l2CacheSize = info.l2CacheSize_;
  deviceProps.maxThreadsPerMultiProcessor = info.maxThreadsPerCU_;
  deviceProps.computeMode = 0;
  deviceProps.clockInstructionRate = info.timeStampFrequency_;
  deviceProps.arch.hasGlobalInt32Atomics       = 1;
  deviceProps.arch.hasGlobalFloatAtomicExch    = 1;
  deviceProps.arch.hasSharedInt32Atomics       = 1;
  deviceProps.arch.hasSharedFloatAtomicExch    = 1;
  deviceProps.arch.hasFloatAtomicAdd           = 1;
  deviceProps.arch.hasGlobalInt64Atomics       = 1;
  deviceProps.arch.hasSharedInt64Atomics       = 1;
  deviceProps.arch.hasDoubles                  = 1;
  deviceProps.arch.hasWarpVote                 = 1;
  deviceProps.arch.hasWarpBallot               = 1;
  deviceProps.arch.hasWarpShuffle              = 1;
  deviceProps.arch.hasFunnelShift              = 0;
  deviceProps.arch.hasThreadFenceSystem        = 1;
  deviceProps.arch.hasSyncThreadsExt           = 0;
  deviceProps.arch.hasSurfaceFuncs             = 0;
  deviceProps.arch.has3dGrid                   = 1;
  deviceProps.arch.hasDynamicParallelism       = 0;
  deviceProps.concurrentKernels = 1;
  deviceProps.pciDomainID = info.pciDomainID;
  deviceProps.pciBusID = info.deviceTopology_.pcie.bus;
  deviceProps.pciDeviceID = info.deviceTopology_.pcie.device;
  deviceProps.maxSharedMemoryPerMultiProcessor = info.localMemSizePerCU_;
  deviceProps.canMapHostMemory = 1;
  //FIXME: This should be removed, targets can have character names as well.
  deviceProps.gcnArch = info.gfxipMajor_ * 100 + info.gfxipMinor_ * 10 + info.gfxipStepping_;
  sprintf(deviceProps.gcnArchName, "%s", info.name_);
  deviceProps.cooperativeLaunch = info.cooperativeGroups_;
  deviceProps.cooperativeMultiDeviceLaunch = info.cooperativeMultiDeviceGroups_;

  deviceProps.cooperativeMultiDeviceUnmatchedFunc = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedGridDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedBlockDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedSharedMem = info.cooperativeMultiDeviceGroups_;

  deviceProps.maxTexture1DLinear = 16 * info.imageMaxBufferSize_; // Max pixel size is 16 bytes
  deviceProps.maxTexture1D = info.image1DMaxWidth_;
  deviceProps.maxTexture2D[0] = info.image2DMaxWidth_;
  deviceProps.maxTexture2D[1] = info.image2DMaxHeight_;
  deviceProps.maxTexture3D[0] = info.image3DMaxWidth_;
  deviceProps.maxTexture3D[1] = info.image3DMaxHeight_;
  deviceProps.maxTexture3D[2] = info.image3DMaxDepth_;
  deviceProps.hdpMemFlushCntl = nullptr;
  deviceProps.hdpRegFlushCntl = nullptr;

  deviceProps.memPitch = info.maxMemAllocSize_;
  deviceProps.textureAlignment = info.imageBaseAddressAlignment_;
  deviceProps.texturePitchAlignment = info.imagePitchAlignment_;
  deviceProps.kernelExecTimeoutEnabled = 0;
  deviceProps.ECCEnabled = info.errorCorrectionSupport_? 1:0;
  deviceProps.isLargeBar = info.largeBar_ ? 1 : 0;
  deviceProps.asicRevision = info.asicRevision_;

  // HMM capabilities
  deviceProps.managedMemory = info.hmmSupported_;
  deviceProps.concurrentManagedAccess =  info.hmmSupported_;
  deviceProps.directManagedMemAccessFromHost = info.hmmDirectHostAccess_;
  deviceProps.pageableMemoryAccess = info.hmmCpuMemoryAccessible_;
  deviceProps.pageableMemoryAccessUsesHostPageTables = info.hostUnifiedMemory_;

  *props = deviceProps;
  HIP_RETURN(hipSuccess);
}
<commit_msg>Use ROCclr Info.targetId_<commit_after>/* Copyright (c) 2018-present Advanced Micro Devices, Inc.

 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 <hip/hip_runtime.h>

#include "hip_internal.hpp"

namespace hip {

// ================================================================================================
amd::HostQueue* Device::NullStream(bool skip_alloc) {
  amd::HostQueue* null_queue = null_stream_.asHostQueue(skip_alloc);
  if (null_queue == nullptr) {
    return nullptr;
  }
  // Wait for all active streams before executing commands on the default
  iHipWaitActiveStreams(null_queue);
  return null_queue;
}

}

hipError_t hipDeviceGet(hipDevice_t *device, int deviceId) {
  HIP_INIT_API(hipDeviceGet, device, deviceId);

  if (device != nullptr) {
    *device = deviceId;
  } else {
    HIP_RETURN(hipErrorInvalidValue);
  }

  HIP_RETURN(hipSuccess);
};

hipError_t hipDeviceTotalMem (size_t *bytes, hipDevice_t device) {

  HIP_INIT_API(hipDeviceTotalMem, bytes, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (bytes == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();

  *bytes = info.globalMemSize_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device) {

  HIP_INIT_API(hipDeviceComputeCapability, major, minor, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (major == nullptr || minor == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  *major = info.gfxipMajor_;
  *minor = info.gfxipMinor_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceGetCount(int* count) {
  HIP_INIT_API(hipDeviceGetCount, count);

  HIP_RETURN(ihipDeviceGetCount(count));
}

hipError_t ihipDeviceGetCount(int* count) {
  if (count == nullptr) {
    return hipErrorInvalidValue;
  }

  // Get all available devices
  *count = g_devices.size();

  if (*count < 1) {
    return hipErrorNoDevice;
  }

  return hipSuccess;
}

hipError_t hipDeviceGetName(char *name, int len, hipDevice_t device) {

  HIP_INIT_API(hipDeviceGetName, (void*)name, len, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (name == nullptr || len <= 0) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  const auto nameLen = ::strlen(info.boardName_);

  // Make sure that the size of `dest` is big enough to hold `src` including
  // trailing zero byte
  if (nameLen > (cl_uint)(len - 1)) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  ::strncpy(name, info.boardName_, (nameLen + 1));

  HIP_RETURN(hipSuccess);
}

hipError_t hipGetDeviceProperties ( hipDeviceProp_t* props, hipDevice_t device ) {
  HIP_INIT_API(hipGetDeviceProperties, props, device);

  if (props == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  if (unsigned(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }
  auto* deviceHandle = g_devices[device]->devices()[0];

  hipDeviceProp_t deviceProps = {0};

  const auto& info = deviceHandle->info();
  ::strncpy(deviceProps.name, info.boardName_, 128);
  deviceProps.totalGlobalMem = info.globalMemSize_;
  deviceProps.sharedMemPerBlock = info.localMemSizePerCU_;
  deviceProps.regsPerBlock = info.availableRegistersPerCU_;
  deviceProps.warpSize = info.wavefrontWidth_;
  deviceProps.maxThreadsPerBlock = info.maxWorkGroupSize_;
  deviceProps.maxThreadsDim[0] = info.maxWorkItemSizes_[0];
  deviceProps.maxThreadsDim[1] = info.maxWorkItemSizes_[1];
  deviceProps.maxThreadsDim[2] = info.maxWorkItemSizes_[2];
  deviceProps.maxGridSize[0] = INT32_MAX;
  deviceProps.maxGridSize[1] = INT32_MAX;
  deviceProps.maxGridSize[2] = INT32_MAX;
  deviceProps.clockRate = info.maxEngineClockFrequency_ * 1000;
  deviceProps.memoryClockRate = info.maxMemoryClockFrequency_ * 1000;
  deviceProps.memoryBusWidth = info.globalMemChannels_;
  deviceProps.totalConstMem = info.maxConstantBufferSize_;
  deviceProps.major = info.gfxipMajor_;
  deviceProps.minor = info.gfxipMinor_;
  deviceProps.multiProcessorCount = info.maxComputeUnits_;
  deviceProps.l2CacheSize = info.l2CacheSize_;
  deviceProps.maxThreadsPerMultiProcessor = info.maxThreadsPerCU_;
  deviceProps.computeMode = 0;
  deviceProps.clockInstructionRate = info.timeStampFrequency_;
  deviceProps.arch.hasGlobalInt32Atomics       = 1;
  deviceProps.arch.hasGlobalFloatAtomicExch    = 1;
  deviceProps.arch.hasSharedInt32Atomics       = 1;
  deviceProps.arch.hasSharedFloatAtomicExch    = 1;
  deviceProps.arch.hasFloatAtomicAdd           = 1;
  deviceProps.arch.hasGlobalInt64Atomics       = 1;
  deviceProps.arch.hasSharedInt64Atomics       = 1;
  deviceProps.arch.hasDoubles                  = 1;
  deviceProps.arch.hasWarpVote                 = 1;
  deviceProps.arch.hasWarpBallot               = 1;
  deviceProps.arch.hasWarpShuffle              = 1;
  deviceProps.arch.hasFunnelShift              = 0;
  deviceProps.arch.hasThreadFenceSystem        = 1;
  deviceProps.arch.hasSyncThreadsExt           = 0;
  deviceProps.arch.hasSurfaceFuncs             = 0;
  deviceProps.arch.has3dGrid                   = 1;
  deviceProps.arch.hasDynamicParallelism       = 0;
  deviceProps.concurrentKernels = 1;
  deviceProps.pciDomainID = info.pciDomainID;
  deviceProps.pciBusID = info.deviceTopology_.pcie.bus;
  deviceProps.pciDeviceID = info.deviceTopology_.pcie.device;
  deviceProps.maxSharedMemoryPerMultiProcessor = info.localMemSizePerCU_;
  deviceProps.canMapHostMemory = 1;
  //FIXME: This should be removed, targets can have character names as well.
  deviceProps.gcnArch = info.gfxipMajor_ * 100 + info.gfxipMinor_ * 10 + info.gfxipStepping_;
  sprintf(deviceProps.gcnArchName, "%s", info.targetId_);
  deviceProps.cooperativeLaunch = info.cooperativeGroups_;
  deviceProps.cooperativeMultiDeviceLaunch = info.cooperativeMultiDeviceGroups_;

  deviceProps.cooperativeMultiDeviceUnmatchedFunc = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedGridDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedBlockDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedSharedMem = info.cooperativeMultiDeviceGroups_;

  deviceProps.maxTexture1DLinear = 16 * info.imageMaxBufferSize_; // Max pixel size is 16 bytes
  deviceProps.maxTexture1D = info.image1DMaxWidth_;
  deviceProps.maxTexture2D[0] = info.image2DMaxWidth_;
  deviceProps.maxTexture2D[1] = info.image2DMaxHeight_;
  deviceProps.maxTexture3D[0] = info.image3DMaxWidth_;
  deviceProps.maxTexture3D[1] = info.image3DMaxHeight_;
  deviceProps.maxTexture3D[2] = info.image3DMaxDepth_;
  deviceProps.hdpMemFlushCntl = nullptr;
  deviceProps.hdpRegFlushCntl = nullptr;

  deviceProps.memPitch = info.maxMemAllocSize_;
  deviceProps.textureAlignment = info.imageBaseAddressAlignment_;
  deviceProps.texturePitchAlignment = info.imagePitchAlignment_;
  deviceProps.kernelExecTimeoutEnabled = 0;
  deviceProps.ECCEnabled = info.errorCorrectionSupport_? 1:0;
  deviceProps.isLargeBar = info.largeBar_ ? 1 : 0;
  deviceProps.asicRevision = info.asicRevision_;

  // HMM capabilities
  deviceProps.managedMemory = info.hmmSupported_;
  deviceProps.concurrentManagedAccess =  info.hmmSupported_;
  deviceProps.directManagedMemAccessFromHost = info.hmmDirectHostAccess_;
  deviceProps.pageableMemoryAccess = info.hmmCpuMemoryAccessible_;
  deviceProps.pageableMemoryAccessUsesHostPageTables = info.hostUnifiedMemory_;

  *props = deviceProps;
  HIP_RETURN(hipSuccess);
}
<|endoftext|>


<commit_before>#include "hip_fatbin.hpp"

#include "hip_code_object.hpp"

namespace hip {

FatBinaryDeviceInfo::~FatBinaryDeviceInfo() {
  if (program_ != nullptr) {
    program_->release();
    program_ = nullptr;
  }
}

FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image)
               : fdesc_(-1), fsize_(0), image_(image), uri_(std::string()) {
  guarantee(fname || image);

  if (fname != nullptr) {
    fname_ = std::string(fname);
  } else {
    fname_ = std::string();
  }

  fatbin_dev_info_.resize(g_devices.size());
}

FatBinaryInfo::~FatBinaryInfo() {

  for (auto& fbd: fatbin_dev_info_) {
    delete fbd;
  }

  if (fdesc_ > 0) {
    if (!amd::Os::CloseFileHandle(fdesc_)) {
      guarantee(false && "Cannot close file");
    }

    if (!amd::Os::MemoryUnmapFile(image_, fsize_)) {
      guarantee(false && "Cannot unmap file");
    }
  }

  fname_ = std::string();
  fdesc_ = -1;
  fsize_ = 0;
  image_ = nullptr;
  uri_ = std::string();
}

hipError_t FatBinaryInfo::ExtractFatBinary(const std::vector<hip::Device*>& devices) {
  hipError_t hip_error = hipSuccess;
  std::vector<std::pair<const void*, size_t>> code_objs;
  code_objs.resize(devices.size());

  // Copy device names for Extract Code object File
  std::vector<const char*> device_names;
  for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
    device_names.push_back(devices[dev_idx]->devices()[0]->info().name_);
  }

  // We are given file name, get the file desc and file size
  if (fname_.size() > 0) {
    // Get File Handle & size of the file.
    if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_)) {
      return hipErrorFileNotFound;
    }

    // Extract the code object from file
    hip_error = CodeObject::ExtractCodeObjectFromFile(fdesc_, fsize_,
                device_names, code_objs);

    // Map the file memory, Later: only map offset, throws error in ElfMagic now.
    if (!amd::Os::MemoryMapFileDesc(fdesc_, fsize_, 0, &image_)) {
      return hipErrorInvalidValue;
    }

  } else if (image_ != nullptr) {
    // We are directly given image pointer directly, try to extract file desc & file Size
    hip_error = CodeObject::ExtractCodeObjectFromMemory(image_,
                device_names, code_objs, uri_);
  } else {
    return hipErrorMissingConfiguration;
  }

  if (hip_error == hipErrorNoBinaryForGpu) {
    guarantee(false && "hipErrorNoBinaryForGpu: Coudn't find binary for current devices!");
    return hip_error;
  }

  if (hip_error == hipErrorInvalidKernelFile) {
    for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
      // the image type is no CLANG_OFFLOAD_BUNDLER, image for current device directly passed
      fatbin_dev_info_[devices[dev_idx]->deviceId()]
        = new FatBinaryDeviceInfo(image_, CodeObject::ElfSize(image_), 0);
    }
  } else if(hip_error == hipSuccess) {
    for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
      // Calculate the offset wrt binary_image and the original image
      size_t offset_l
        = (reinterpret_cast<address>(const_cast<void*>(code_objs[dev_idx].first))
            - reinterpret_cast<address>(const_cast<void*>(image_)));

      fatbin_dev_info_[devices[dev_idx]->deviceId()]
        = new FatBinaryDeviceInfo(code_objs[dev_idx].first, code_objs[dev_idx].second, offset_l);
    }
  }

  for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
    fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_
       = new amd::Program(*devices[dev_idx]->asContext());
    if (fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_ == NULL) {
      return hipErrorOutOfMemory;
    }
  }

  return hipSuccess;
}

hipError_t FatBinaryInfo::AddDevProgram(const int device_id) {
  // Device Id bounds Check
  DeviceIdCheck(device_id);

  FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
  // If fat binary was already added, skip this step and return success
  if (fbd_info->add_dev_prog_ == false) {
    amd::Context* ctx = g_devices[device_id]->asContext();
    if (CL_SUCCESS != fbd_info->program_->addDeviceProgram(*ctx->devices()[0],
                                          fbd_info->binary_image_,
                                          fbd_info->binary_size_, false,
                                          nullptr, nullptr, fdesc_,
                                          fbd_info->binary_offset_, uri_)) {
      return hipErrorInvalidKernelFile;
    }
    fbd_info->add_dev_prog_ = true;
  }
  return hipSuccess;
}

hipError_t FatBinaryInfo::BuildProgram(const int device_id) {

  // Device Id Check and Add DeviceProgram if not added so far
  DeviceIdCheck(device_id);
  IHIP_RETURN_ONFAIL(AddDevProgram(device_id));

  // If Program was already built skip this step and return success
  FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
  if (fbd_info->prog_built_ == false) {
    if(CL_SUCCESS != fbd_info->program_->build(g_devices[device_id]->devices(),
                                               nullptr, nullptr, nullptr,
                                               kOptionChangeable, kNewDevProg)) {
      return hipErrorSharedObjectInitFailed;
    }
    fbd_info->prog_built_ = true;
  }
  return hipSuccess;
}

} //namespace : hip
<commit_msg>SWDEV-252542 - Fixing Win Compilation on SWDEV-241902.<commit_after>#include "hip_fatbin.hpp"

#include "hip_code_object.hpp"

namespace hip {

FatBinaryDeviceInfo::~FatBinaryDeviceInfo() {
  if (program_ != nullptr) {
    program_->release();
    program_ = nullptr;
  }
}

FatBinaryInfo::FatBinaryInfo(const char* fname, const void* image)
               : fdesc_(amd::Os::FDescInit()), fsize_(0), image_(image), uri_(std::string()) {
  guarantee(fname || image);

  if (fname != nullptr) {
    fname_ = std::string(fname);
  } else {
    fname_ = std::string();
  }

  fatbin_dev_info_.resize(g_devices.size());
}

FatBinaryInfo::~FatBinaryInfo() {

  for (auto& fbd: fatbin_dev_info_) {
    delete fbd;
  }

  if (fdesc_ > 0) {
    if (!amd::Os::CloseFileHandle(fdesc_)) {
      guarantee(false && "Cannot close file");
    }

    if (!amd::Os::MemoryUnmapFile(image_, fsize_)) {
      guarantee(false && "Cannot unmap file");
    }
  }

  fname_ = std::string();
  fdesc_ = amd::Os::FDescInit();
  fsize_ = 0;
  image_ = nullptr;
  uri_ = std::string();
}

hipError_t FatBinaryInfo::ExtractFatBinary(const std::vector<hip::Device*>& devices) {
  hipError_t hip_error = hipSuccess;
  std::vector<std::pair<const void*, size_t>> code_objs;
  code_objs.resize(devices.size());

  // Copy device names for Extract Code object File
  std::vector<const char*> device_names;
  for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
    device_names.push_back(devices[dev_idx]->devices()[0]->info().name_);
  }

  // We are given file name, get the file desc and file size
  if (fname_.size() > 0) {
    // Get File Handle & size of the file.
    if (!amd::Os::GetFileHandle(fname_.c_str(), &fdesc_, &fsize_)) {
      return hipErrorFileNotFound;
    }

    // Extract the code object from file
    hip_error = CodeObject::ExtractCodeObjectFromFile(fdesc_, fsize_,
                device_names, code_objs);

    // Map the file memory, Later: only map offset, throws error in ElfMagic now.
    if (!amd::Os::MemoryMapFileDesc(fdesc_, fsize_, 0, &image_)) {
      return hipErrorInvalidValue;
    }

  } else if (image_ != nullptr) {
    // We are directly given image pointer directly, try to extract file desc & file Size
    hip_error = CodeObject::ExtractCodeObjectFromMemory(image_,
                device_names, code_objs, uri_);
  } else {
    return hipErrorMissingConfiguration;
  }

  if (hip_error == hipErrorNoBinaryForGpu) {
    guarantee(false && "hipErrorNoBinaryForGpu: Coudn't find binary for current devices!");
    return hip_error;
  }

  if (hip_error == hipErrorInvalidKernelFile) {
    for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
      // the image type is no CLANG_OFFLOAD_BUNDLER, image for current device directly passed
      fatbin_dev_info_[devices[dev_idx]->deviceId()]
        = new FatBinaryDeviceInfo(image_, CodeObject::ElfSize(image_), 0);
    }
  } else if(hip_error == hipSuccess) {
    for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
      // Calculate the offset wrt binary_image and the original image
      size_t offset_l
        = (reinterpret_cast<address>(const_cast<void*>(code_objs[dev_idx].first))
            - reinterpret_cast<address>(const_cast<void*>(image_)));

      fatbin_dev_info_[devices[dev_idx]->deviceId()]
        = new FatBinaryDeviceInfo(code_objs[dev_idx].first, code_objs[dev_idx].second, offset_l);
    }
  }

  for (size_t dev_idx = 0; dev_idx < devices.size(); ++dev_idx) {
    fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_
       = new amd::Program(*devices[dev_idx]->asContext());
    if (fatbin_dev_info_[devices[dev_idx]->deviceId()]->program_ == NULL) {
      return hipErrorOutOfMemory;
    }
  }

  return hipSuccess;
}

hipError_t FatBinaryInfo::AddDevProgram(const int device_id) {
  // Device Id bounds Check
  DeviceIdCheck(device_id);

  FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
  // If fat binary was already added, skip this step and return success
  if (fbd_info->add_dev_prog_ == false) {
    amd::Context* ctx = g_devices[device_id]->asContext();
    if (CL_SUCCESS != fbd_info->program_->addDeviceProgram(*ctx->devices()[0],
                                          fbd_info->binary_image_,
                                          fbd_info->binary_size_, false,
                                          nullptr, nullptr, fdesc_,
                                          fbd_info->binary_offset_, uri_)) {
      return hipErrorInvalidKernelFile;
    }
    fbd_info->add_dev_prog_ = true;
  }
  return hipSuccess;
}

hipError_t FatBinaryInfo::BuildProgram(const int device_id) {

  // Device Id Check and Add DeviceProgram if not added so far
  DeviceIdCheck(device_id);
  IHIP_RETURN_ONFAIL(AddDevProgram(device_id));

  // If Program was already built skip this step and return success
  FatBinaryDeviceInfo* fbd_info = fatbin_dev_info_[device_id];
  if (fbd_info->prog_built_ == false) {
    if(CL_SUCCESS != fbd_info->program_->build(g_devices[device_id]->devices(),
                                               nullptr, nullptr, nullptr,
                                               kOptionChangeable, kNewDevProg)) {
      return hipErrorSharedObjectInitFailed;
    }
    fbd_info->prog_built_ = true;
  }
  return hipSuccess;
}

} //namespace : hip
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

/*
 * Abstraction for GL window system specific APIs (GLX, WGL).
 */

#ifndef _GLWS_HPP_
#define _GLWS_HPP_

#include <assert.h>

#include <vector>
#include <set>
#include <string>
#include <ostream>

namespace glws {

enum Api {
    API_GL = 0,
    API_GLES
};

struct Profile {
    Api api;
    unsigned major;
    unsigned minor;
    bool core;

    inline
    Profile(Api _api = API_GL, unsigned _major = 1, unsigned _minor = 0, bool _core = false) {
        api = _api;
        major = _major;
        minor = _minor;
        core = _core;
    }

    inline bool
    versionGreaterOrEqual(unsigned refMajor, unsigned refMinor) const {
        return major > refMajor ||
               (major == refMajor && minor >= refMinor);
    }

    // Comparison operator, mainly for use in std::map
    inline bool
    operator < (const Profile & other) const {
        return api < other.api ||
               major < other.major ||
               minor < other.minor ||
               (int)core < (int)other.core;
    }
};

inline std::ostream &
operator << (std::ostream &os, const Profile & profile) {
    os << "OpenGL";
    if (profile.api == API_GLES) {
        os << " ES";
    }
    os << " " << profile.major << "." << profile.minor;
    if (profile.api == API_GL &&
        profile.versionGreaterOrEqual(3, 2)) {
        os << " " << (profile.core ? "core" : "compat");
    }
    return os;
}

bool
checkExtension(const char *extName, const char *extString);

template< class T >
class Attributes {
protected:
    std::vector<T> attribs;

public:
    void add(T param) {
        attribs.push_back(param);
    }

    void add(T pname, T pvalue) {
        add(pname);
        add(pvalue);
    }

    void end(T terminator = 0) {
        add(terminator);
    }

    operator T * (void) {
        return &attribs[0];
    }

    operator const T * (void) const {
        return &attribs[0];
    }
};

class Visual
{
public:
    Profile profile;

    /* TODO */
#if 0
    unsigned long redMask;
    unsigned long greenMask;
    unsigned long blueMask;
    unsigned long alphaMask;
#endif
    bool doubleBuffer;

    Visual(Profile prof) :
        profile(prof)
    {}

    virtual ~Visual() {}
};

class Drawable
{
public:
    const Visual *visual;
    int width;
    int height;
    bool pbuffer;
    bool visible;

    Drawable(const Visual *vis, int w, int h, bool pb) :
        visual(vis),
        width(w),
        height(h),
        pbuffer(pb),
        visible(false)
    {}

    virtual ~Drawable() {}

    virtual void
    resize(int w, int h) {
        width = w;
        height = h;
    }

    virtual void
    show(void) {
        assert(!pbuffer);
        visible = true;
    }

    virtual void copySubBuffer(int x, int y, int width, int height);

    virtual void swapBuffers(void) = 0;
};

class Context
{
public:
    const Visual *visual;
    Profile profile;

    std::set<std::string> extensions;

    Context(const Visual *vis) :
        visual(vis),
        profile(vis->profile)
    {}

    virtual ~Context() {}

    // Context must be current
    bool
    hasExtension(const char *extension);
};

void
init(void);

void
cleanup(void);

Visual *
createVisual(bool doubleBuffer, unsigned samples, Profile profile);

Drawable *
createDrawable(const Visual *visual, int width, int height, bool pbuffer = false);

bool
bindApi(Api api);

Context *
createContext(const Visual *visual, Context *shareContext = 0, bool debug = false);

bool
makeCurrent(Drawable *drawable, Context *context);

bool
processEvents(void);

} /* namespace glws */

#endif /* _GLWS_HPP_ */
<commit_msg>glws: Pack Profile structure.<commit_after>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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.
 *
 **************************************************************************/

/*
 * Abstraction for GL window system specific APIs (GLX, WGL).
 */

#ifndef _GLWS_HPP_
#define _GLWS_HPP_

#include <assert.h>

#include <vector>
#include <set>
#include <string>
#include <ostream>

namespace glws {

enum Api {
    API_GL = 0,
    API_GLES
};

struct Profile {
    unsigned major:8;
    unsigned minor:8;
    unsigned api:1;
    unsigned core:1;

    inline
    Profile(Api _api = API_GL, unsigned _major = 1, unsigned _minor = 0, bool _core = false) {
        api = _api;
        major = _major;
        minor = _minor;
        core = _core;
    }

    inline bool
    versionGreaterOrEqual(unsigned refMajor, unsigned refMinor) const {
        return major > refMajor ||
               (major == refMajor && minor >= refMinor);
    }

    // Comparison operator, mainly for use in std::map
    inline bool
    operator < (const Profile & other) const {
        return api < other.api ||
               major < other.major ||
               minor < other.minor ||
               core < other.core;
    }
};

inline std::ostream &
operator << (std::ostream &os, const Profile & profile) {
    os << "OpenGL";
    if (profile.api == API_GLES) {
        os << " ES";
    }
    os << " " << profile.major << "." << profile.minor;
    if (profile.api == API_GL &&
        profile.versionGreaterOrEqual(3, 2)) {
        os << " " << (profile.core ? "core" : "compat");
    }
    return os;
}

bool
checkExtension(const char *extName, const char *extString);

template< class T >
class Attributes {
protected:
    std::vector<T> attribs;

public:
    void add(T param) {
        attribs.push_back(param);
    }

    void add(T pname, T pvalue) {
        add(pname);
        add(pvalue);
    }

    void end(T terminator = 0) {
        add(terminator);
    }

    operator T * (void) {
        return &attribs[0];
    }

    operator const T * (void) const {
        return &attribs[0];
    }
};

class Visual
{
public:
    Profile profile;

    /* TODO */
#if 0
    unsigned long redMask;
    unsigned long greenMask;
    unsigned long blueMask;
    unsigned long alphaMask;
#endif
    bool doubleBuffer;

    Visual(Profile prof) :
        profile(prof)
    {}

    virtual ~Visual() {}
};

class Drawable
{
public:
    const Visual *visual;
    int width;
    int height;
    bool pbuffer;
    bool visible;

    Drawable(const Visual *vis, int w, int h, bool pb) :
        visual(vis),
        width(w),
        height(h),
        pbuffer(pb),
        visible(false)
    {}

    virtual ~Drawable() {}

    virtual void
    resize(int w, int h) {
        width = w;
        height = h;
    }

    virtual void
    show(void) {
        assert(!pbuffer);
        visible = true;
    }

    virtual void copySubBuffer(int x, int y, int width, int height);

    virtual void swapBuffers(void) = 0;
};

class Context
{
public:
    const Visual *visual;
    Profile profile;

    std::set<std::string> extensions;

    Context(const Visual *vis) :
        visual(vis),
        profile(vis->profile)
    {}

    virtual ~Context() {}

    // Context must be current
    bool
    hasExtension(const char *extension);
};

void
init(void);

void
cleanup(void);

Visual *
createVisual(bool doubleBuffer, unsigned samples, Profile profile);

Drawable *
createDrawable(const Visual *visual, int width, int height, bool pbuffer = false);

bool
bindApi(Api api);

Context *
createContext(const Visual *visual, Context *shareContext = 0, bool debug = false);

bool
makeCurrent(Drawable *drawable, Context *context);

bool
processEvents(void);

} /* namespace glws */

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


<commit_before>/*
Copyright 2012 Cloudbase Solutions Srl
All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/

#pragma region Includes
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "ServiceBase.h"
#include "OpenStackService.h"
#pragma endregion

int wmain(int argc, wchar_t *argv[])
{
    if(argc <= 2)
    {
        wprintf(L"Usage: OpenStackService <ServiceName> <PythonExe> [Arguments]\n");
        return -1;
    }

    TCHAR cmdLine[MAX_SVC_PATH];
    cmdLine[0] = NULL;
    for(int i = 2; i < argc; i++)
    {
        TCHAR buf[MAX_SVC_PATH];
        if(i > 2)
            _tcscat_s(cmdLine, MAX_SVC_PATH, _T(" "));
        _stprintf_s(buf, _T("\"%s\""), argv[i]);
        _tcscat_s(cmdLine, MAX_SVC_PATH, buf);
    }

    CWrapperService service(argv[1], cmdLine);
    if (!CServiceBase::Run(service))
    {
        wprintf(L"Service failed to run w/err 0x%08lx\n", GetLastError());
    }

    return 0;
}
<commit_msg>Add environment file support and improve option parsing<commit_after>/*
Copyright 2012 Cloudbase Solutions Srl
All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/

#pragma region Includes
#include <stdio.h>
#include <windows.h>
#include <boost/program_options.hpp>
#include <boost/algorithm/string/join.hpp>
#include <iostream>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <vector>
#include "ServiceBase.h"
#include "OpenStackService.h"
#pragma endregion

using namespace std;
using namespace boost::program_options;

struct CLIArgs
{
    wstring environmentFile;
    wstring execStartPre;
    wstring serviceName;
    vector<wstring> additionalArgs;
};

CLIArgs ParseArgs(int argc, wchar_t *argv[]);
EnvMap LoadEnvVarsFromFile(const wstring& path);

CLIArgs ParseArgs(int argc, wchar_t *argv[])
{
    CLIArgs args;
    options_description desc{ "Options" };
    desc.add_options()
        ("environment-file,e", wvalue<wstring>(), "Environment file")
        ("exec-start-pre", wvalue<wstring>(), "Command to be executed before starting the service")
        ("service-name,n", wvalue<wstring>(), "Service name");

    variables_map vm;
    auto parsed = wcommand_line_parser(argc, argv).
        options(desc).allow_unregistered().run();
    store(parsed, vm);
    auto additionalArgs = collect_unrecognized(parsed.options, include_positional);
    notify(vm);

    if (vm.count("environment-file"))
        args.environmentFile = vm["environment-file"].as<wstring>();

    if (vm.count("exec-start-pre"))
        args.execStartPre = vm["exec-start-pre"].as<wstring>();

    if (vm.count("service-name"))
        args.serviceName = vm["service-name"].as<wstring>();
    else if (!additionalArgs.empty())
    {
        args.serviceName = additionalArgs[0];
        additionalArgs = vector<wstring>(additionalArgs.begin() + 1, additionalArgs.end());
    }

    if(args.serviceName.empty())
        throw exception("Service name not provided");

    args.additionalArgs = additionalArgs;
    if (args.additionalArgs.empty())
        throw exception("Service executable not provided");

    return args;
}

EnvMap LoadEnvVarsFromFile(const wstring& path)
{
    wifstream inputFile(path);
    wstring line;
    EnvMap env;

    while (getline(inputFile, line))
    {
        wistringstream ss(line);
        wregex rgx(L"^([^=]+)=(.*)$");
        wsmatch matches;
        if (regex_search(line, matches, rgx))
        {
            auto name = matches[1];
            auto value = matches[2];
            env[name] = value;
        }
    }

    return env;
}

int wmain(int argc, wchar_t *argv[])
{
    try
    {
        EnvMap env;
        auto args = ParseArgs(argc, argv);
        if (!args.environmentFile.empty())
            env = LoadEnvVarsFromFile(args.environmentFile);

        auto it = args.additionalArgs.begin();
        wstring cmdLine = *it++;
        for (; it != args.additionalArgs.end(); ++it)
            cmdLine += L" \"" + *it + L"\"";

        CWrapperService service(args.serviceName.c_str(), cmdLine.c_str(), env);
        if (!CServiceBase::Run(service))
        {
            char msg[100];
            sprintf_s(msg, "Service failed to run w/err 0x%08lx", GetLastError());
            throw exception(msg);
        }

        return 0;
    }
    catch (exception &ex)
    {
        std::cerr << ex.what() << '\n';
        return -1;
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/shm.h>

#include <stdlib.h>
#include <string.h>
#include <termios.h>

#include "tangram.h"
#include "platform.h"
#include "gl.h"

#include "util/shaderProgram.h"
#include "util/vertexLayout.h"
#include "util/vboMesh.h"
#include "util/geom.h"

#define KEY_ESC		113    // q
#define KEY_ZOOM_IN 45     // -
#define KEY_ZOOM_OUT 61    // =
#define KEY_UP 		119    // w
#define KEY_LEFT 	97     // a
#define KEY_RIGHT 	115    // s
#define KEY_DOWN 	122    // z

struct timeval tv;

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;

    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

} CUBE_STATE_T;
static CUBE_STATE_T _state, *state=&_state;

typedef struct Mouse {
    Mouse():x(0),y(0),button(0){};

    float   x,y;
    float   velX,velY;
    int     button;
};
static Mouse mouse;

ShaderProgram mouseShader;
std::string mouseVertex =
"precision mediump float;\n"
"uniform float u_time;\n"
"uniform vec2 u_mouse;\n"
"uniform vec2 u_resolution;\n"
"attribute vec4 a_position;\n"
"attribute vec4 a_color;\n"
"varying vec4 v_color;\n"
"void main(void) {\n"
"    gl_Position = (a_position*0.5);\n"
"    v_color = a_color;\n"
"}\n";

std::string mouseFragment =
"precision mediump float;\n"
"uniform float u_time;\n"
"uniform vec2 u_mouse;\n"
"uniform vec2 u_resolution;\n"
"varying vec4 v_color;\n"
"void main(void) {\n"
"    gl_FragColor = v_color;\n"
"}\n";

struct PosColorVertex {
    // Position Data
    GLfloat pos_x;
    GLfloat pos_y;
    GLfloat pos_z;
    // Color Data
    GLuint abgr;
};
VboMesh* mouseMesh;

static void initOpenGL(){
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_DEPTH_SIZE, 16,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

    // Prepare viewport
    glViewport( 0, 0, state->screen_width, state->screen_height );

    // Prepair Mouse Shader
    mouseShader.setSourceStrings(mouseVertex,mouseFragment);

    std::vector<VertexLayout::VertexAttrib> attribs;
    attribs.push_back({"a_position", 3, GL_FLOAT, false, 0});
    attribs.push_back({"a_color", 4, GL_UNSIGNED_BYTE, true, 0});
    VertexLayout* vertexLayout = new VertexLayout(attribs);

    std::vector<PosColorVertex> vertices;
    std::vector<GLushort> indices;

    // Small billboard for the mouse
    float size = 10.0;
    {
        float x = mapValue(state->screen_width*0.5f-size*0.5f,0,state->screen_width,-1.0f,1.0f);
        float y = mapValue(state->screen_height*0.5f-size*0.5f,0,state->screen_height,-1,1);
        float w = mapValue(size,0,state->screen_width,0,2.0);
        float h = mapValue(size,0,state->screen_height,0,2.0);

        vertices.push_back({ x, y, 1.0, 0.0, 0.0 });
        vertices.push_back({ x+w, y, 1.0, 1.0, 0.0 });
        vertices.push_back({ x+w, y+h, 1.0, 1.0, 1.0 });
        vertices.push_back({ x, y+h, 1.0, 0.0, 1.0 });

        indices.push_back(0); indices.push_back(1); indices.push_back(2);
        indices.push_back(2); indices.push_back(3); indices.push_back(0);
    }

    mouseMesh = new VboMesh(vertexLayout);
    mouseMesh->addVertices((GLbyte*)vertices.data(), vertices.size());
    mouseMesh->addIndices(indices.data(), indices.size());
}

static bool updateMouse(){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    //static int x=width, y=height;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
        fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {

        // Set values to 0
        mouse.velX=0;
        mouse.velY=0;

        // Extract values from driver
        struct {char buttons, dx, dy; } m;
        while (1) {
            int bytes = read(fd, &m, sizeof m);

            if (bytes < (int)sizeof m) {
                return false;
            } else if (m.buttons&8) {
                break; // This bit should always be set
            }

            read(fd, &m, 1); // Try to sync up again
        }

        // Set button value
        if (m.buttons&3)
            mouse.button = m.buttons&3;
        else
            mouse.button = 0;

        // Set deltas
        mouse.velX=m.dx;
        mouse.velY=m.dy;
        if (m.buttons&XSIGN) mouse.velX-=256;
        if (m.buttons&YSIGN) mouse.velY-=256;

        // Add movement
        mouse.x+=mouse.velX;
        mouse.y+=mouse.velY;

        // Clamp values
        if (mouse.x<0) mouse.x=0;
        if (mouse.y<0) mouse.y=0;
        if (mouse.x>width) mouse.x=width;
        if (mouse.y>height) mouse.y=height;
        return true;
    }
   	return false;
}

int getkey() {
	int character;
	struct termios orig_term_attr;
	struct termios new_term_attr;

	/* set the terminal to raw mode */
	tcgetattr(fileno(stdin), &orig_term_attr);
	memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
	new_term_attr.c_lflag &= ~(ECHO|ICANON);
	new_term_attr.c_cc[VTIME] = 0;
	new_term_attr.c_cc[VMIN] = 0;
	tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);

	/* read a character from the stdin stream without blocking */
	/*   returns EOF (-1) if no character is available */
	character = fgetc(stdin);

	/* restore the original terminal attributes */
	tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);

	return character;
}

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

    // Start OpenGL context
    initOpenGL();

    // Set background color and clear buffers
    Tangram::initialize();
    Tangram::resize(state->screen_width, state->screen_height);

    // Start clock
    gettimeofday(&tv, NULL);
    unsigned long long timePrev = 	(unsigned long long)(tv.tv_sec) * 1000 +
    (unsigned long long)(tv.tv_usec) / 1000;

    bool bContinue = true;
    while (bContinue) {

        // Update
        unsigned long long timeNow = 	(unsigned long long)(tv.tv_sec) * 1000 +
        (unsigned long long)(tv.tv_usec) / 1000;
        double delta = (timeNow - timePrev)*0.001;

        Tangram::update(delta);
        timePrev = timeNow;

        if(updateMouse()){
            if( mouse.button == 1 ){
                Tangram::handlePanGesture( mouse.velX*5.0, -mouse.velY*5.0);
            } else if( mouse.button == 2 ){
                Tangram::handlePinchGesture( 0.0, 0.0, 1.0 + mouse.velY*0.005 );
            }
        }

		int key = getkey();
		if(key != -1){
			switch (key) {
				case KEY_ZOOM_IN:
					Tangram::handlePinchGesture(0.0,0.0,0.5);
					break;
				case KEY_ZOOM_OUT:
					Tangram::handlePinchGesture(0.0,0.0,2.0);
					break;
				case KEY_UP:
					Tangram::handlePanGesture(0.0,100.0);
					break;
				case KEY_DOWN:
					Tangram::handlePanGesture(0.0,-100.0);
					break;
				case KEY_LEFT:
					Tangram::handlePanGesture(100.0,0.0);
					break;
				case KEY_RIGHT:
					Tangram::handlePanGesture(-100.0,0.0);
					break;
                case KEY_ESC:
                    bContinue = false;
                    break;
				default:
					logMsg(" -> %i\n",key);
			}
		}

        // Render
        Tangram::render();

        eglSwapBuffers(state->display, state->surface);
    }

    Tangram::teardown();
    return 0;
}
<commit_msg>adding vbo and shader for mouse<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/shm.h>

#include <stdlib.h>
#include <string.h>
#include <termios.h>

#include "tangram.h"
#include "platform.h"
#include "gl.h"

#include "util/shaderProgram.h"
#include "util/vertexLayout.h"
#include "util/vboMesh.h"
#include "util/geom.h"

#define KEY_ESC		113    // q
#define KEY_ZOOM_IN 45     // -
#define KEY_ZOOM_OUT 61    // =
#define KEY_UP 		119    // w
#define KEY_LEFT 	97     // a
#define KEY_RIGHT 	115    // s
#define KEY_DOWN 	122    // z

struct timeval tv;

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;

    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

} CUBE_STATE_T;
static CUBE_STATE_T _state, *state=&_state;

typedef struct Mouse {
    Mouse():x(0),y(0),button(0){};

    float   x,y;
    float   velX,velY;
    int     button;
};
static Mouse mouse;

std::shared_ptr<ShaderProgram> mouseShader;
std::string mouseVertex =
"precision mediump float;\n"
"uniform float u_time;\n"
"uniform vec2 u_mouse;\n"
"uniform vec2 u_resolution;\n"
"attribute vec4 a_position;\n"
"attribute vec4 a_color;\n"
"varying vec4 v_color;\n"
"void main(void) {\n"
"    gl_Position = (a_position*0.5)+vec4(vec2(u_mouse/u_resolution),0.0,0.0);\n"
"    v_color = a_color;\n"
"}\n";

std::string mouseFragment =
"precision mediump float;\n"
"uniform float u_time;\n"
"uniform vec2 u_mouse;\n"
"uniform vec2 u_resolution;\n"
"varying vec4 v_color;\n"
"void main(void) {\n"
"    gl_FragColor = v_color;\n"
"}\n";

struct PosColorVertex {
    // Position Data
    GLfloat pos_x;
    GLfloat pos_y;
    GLfloat pos_z;
    // Color Data
    GLuint abgr;
};
std::shared_ptr<VboMesh> mouseMesh;

static void initOpenGL(){
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_DEPTH_SIZE, 16,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

    // Prepare viewport
    glViewport( 0, 0, state->screen_width, state->screen_height );

    // Prepair Mouse Shader
    mouseShader = std::shared_ptr<ShaderProgram>(new ShaderProgram());
    mouseShader->setSourceStrings(mouseVertex,mouseFragment);

    std::shared_ptr<VertexLayout> vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
        {"a_position", 3, GL_FLOAT, false, 0},
        {"a_color", 4, GL_UNSIGNED_BYTE, true, 0}
    }));

    std::vector<PosColorVertex> vertices;
    std::vector<int> indices;

    // Small billboard for the mouse
    float size = 10.0;
    GLuint color = 0xffe6f0f2;
    {
        // float x = mapValue(state->screen_width*0.5f-size*0.5f,0,state->screen_width,-1.0f,1.0f);
        // float y = mapValue(state->screen_height*0.5f-size*0.5f,0,state->screen_height,-1,1);
        // float w = mapValue(size,0,state->screen_width,0,2.0);
        // float h = mapValue(size,0,state->screen_height,0,2.0);

        float x = mapValue(0.0f,0.0f,state->screen_width,-1.0f,1.0f);
        float y = mapValue(0.0f,0.0f,state->screen_height,-1.0f,1.0f);
        float w = mapValue(size,0.0f,state->screen_width,0.0f,2.0f);
        float h = mapValue(size,0.0f,state->screen_height,0.0f,2.0f);

        vertices.push_back({ x, y, 0.0, color});
        vertices.push_back({ x+w, y, 0.0, color});
        vertices.push_back({ x+w, y+h, 0.0, color });
        vertices.push_back({ x, y+h, 0.0, color });

        indices.push_back(0); indices.push_back(1); indices.push_back(2);
        indices.push_back(2); indices.push_back(3); indices.push_back(0);
    }

    mouseMesh = std::shared_ptr<VboMesh>(new VboMesh(vertexLayout));
    mouseMesh->addVertices((GLbyte*)vertices.data(), vertices.size());
    mouseMesh->addIndices(indices.data(), indices.size());
}

static bool updateMouse(){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    //static int x=width, y=height;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
        fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {

        // Set values to 0
        mouse.velX=0;
        mouse.velY=0;

        // Extract values from driver
        struct {char buttons, dx, dy; } m;
        while (1) {
            int bytes = read(fd, &m, sizeof m);

            if (bytes < (int)sizeof m) {
                return false;
            } else if (m.buttons&8) {
                break; // This bit should always be set
            }

            read(fd, &m, 1); // Try to sync up again
        }

        // Set button value
        if (m.buttons&3)
            mouse.button = m.buttons&3;
        else
            mouse.button = 0;

        // Set deltas
        mouse.velX=m.dx;
        mouse.velY=m.dy;
        if (m.buttons&XSIGN) mouse.velX-=256;
        if (m.buttons&YSIGN) mouse.velY-=256;

        // Add movement
        mouse.x+=mouse.velX;
        mouse.y+=mouse.velY;

        // Clamp values
        if (mouse.x<0) mouse.x=0;
        if (mouse.y<0) mouse.y=0;
        if (mouse.x>width) mouse.x=width;
        if (mouse.y>height) mouse.y=height;
        return true;
    }
   	return false;
}

int getkey() {
	int character;
	struct termios orig_term_attr;
	struct termios new_term_attr;

	/* set the terminal to raw mode */
	tcgetattr(fileno(stdin), &orig_term_attr);
	memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
	new_term_attr.c_lflag &= ~(ECHO|ICANON);
	new_term_attr.c_cc[VTIME] = 0;
	new_term_attr.c_cc[VMIN] = 0;
	tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);

	/* read a character from the stdin stream without blocking */
	/*   returns EOF (-1) if no character is available */
	character = fgetc(stdin);

	/* restore the original terminal attributes */
	tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);

	return character;
}

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

    // Start OpenGL context
    initOpenGL();

    // Set background color and clear buffers
    Tangram::initialize();
    Tangram::resize(state->screen_width, state->screen_height);

    // Start clock
    gettimeofday(&tv, NULL);
    unsigned long long timePrev = 	(unsigned long long)(tv.tv_sec) * 1000 +
    (unsigned long long)(tv.tv_usec) / 1000;

    bool bContinue = true;
    while (bContinue) {

        // Update
        unsigned long long timeNow = 	(unsigned long long)(tv.tv_sec) * 1000 +
        (unsigned long long)(tv.tv_usec) / 1000;
        double delta = (timeNow - timePrev)*0.001;

        Tangram::update(delta);
        timePrev = timeNow;

        if(updateMouse()){
            if( mouse.button == 1 ){
                Tangram::handlePanGesture( mouse.velX*5.0, -mouse.velY*5.0);
            } else if( mouse.button == 2 ){
                Tangram::handlePinchGesture( 0.0, 0.0, 1.0 + mouse.velY*0.005 );
            }
        }

		int key = getkey();
		if(key != -1){
			switch (key) {
				case KEY_ZOOM_IN:
					Tangram::handlePinchGesture(0.0,0.0,0.5);
					break;
				case KEY_ZOOM_OUT:
					Tangram::handlePinchGesture(0.0,0.0,2.0);
					break;
				case KEY_UP:
					Tangram::handlePanGesture(0.0,100.0);
					break;
				case KEY_DOWN:
					Tangram::handlePanGesture(0.0,-100.0);
					break;
				case KEY_LEFT:
					Tangram::handlePanGesture(100.0,0.0);
					break;
				case KEY_RIGHT:
					Tangram::handlePanGesture(-100.0,0.0);
					break;
                case KEY_ESC:
                    bContinue = false;
                    break;
				default:
					logMsg(" -> %i\n",key);
			}
		}

        // Render
        Tangram::render();

        mouseShader->use();
        mouseShader->setUniformf("u_time", timeNow*0.001);
        mouseShader->setUniformf("u_mouse", mouse.x, mouse.y);
        mouseShader->setUniformf("u_resolution",state->screen_width, state->screen_height);
        mouseMesh->draw(mouseShader);

        eglSwapBuffers(state->display, state->surface);
    }

    Tangram::teardown();
    return 0;
}
<|endoftext|>


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

#include <cstring> // for memcpy()
#include <string>

#include "callbacks.h"
#include "jump.h"
#include "logprintf.h"
#include "wrapper.h"

#include "plugin/plugin.h"

#define AMX_EXEC_CHEAT (-10)

extern void *pAMXFunctions;

static uint32_t amx_Register_addr;
static unsigned char amx_Register_code[5];

static int my_amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, size_t number) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_Register_addr), ::amx_Register_code, 5);
    int error = amx_Register(amx, nativelist, number);

    // Store natives in our global container
    for (size_t i = 0; nativelist[i].name != 0 && (i < number || number == -1); ++i) {
        samp::Wrapper::GetInstance()->SetNative(nativelist[i].name, nativelist[i].func);
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_Register_addr), (void*)::my_amx_Register, ::amx_Register_code);

    return error;
}

static uint32_t amx_FindPublic_addr;
static unsigned char amx_FindPublic_code[5];

static AMX *pGamemode = 0;
static std::string lastPublicName;

static int my_amx_FindPublic(AMX *amx, const char *name, int *index) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_FindPublic_addr), ::amx_FindPublic_code, 5);
    int error = amx_FindPublic(amx, name, index);

    if (amx == ::pGamemode && ::pGamemode != 0) {
        if (error != AMX_ERR_NONE) {
            // The requested public doesn't exist but we say it does
            // to let the server subsequently execute it.
            *index = AMX_EXEC_CHEAT;
            error = AMX_ERR_NONE;
        }
        ::lastPublicName = name;
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_FindPublic_addr), (void*)::my_amx_FindPublic, ::amx_FindPublic_code);

    return error;
}

static uint32_t amx_Exec_addr;
static unsigned char amx_Exec_code[5];

static int my_amx_Exec(AMX *amx, cell *retval, int index) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_Exec_addr), ::amx_Exec_code, 5);

    if (index == AMX_EXEC_MAIN) {
        // main() is being called => this is the gamemode
        ::pGamemode = amx;
        // Manually call OnGameModeInit from here as it's usually called
        // before main() and is impossible to catch using the current method
        samp::Wrapper::GetInstance()->CallPublic(::pGamemode, retval, "OnGameModeInit");
    }

    int error = AMX_ERR_NONE;

    if (amx == ::pGamemode && ::pGamemode != 0) {
        if (index != AMX_EXEC_MAIN && index != AMX_EXEC_CONT) {
            samp::Wrapper::GetInstance()->CallPublic(::pGamemode, retval, ::lastPublicName);
        }
        if (index != AMX_EXEC_CHEAT) {
            // It's calling a fake public (see my_amx_FindPublic for details).
            error = amx_Exec(amx, retval, index);
        }
    } else {
        error = amx_Exec(amx, retval, index);
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::my_amx_Exec, ::amx_Exec_code);

    return error;
}

namespace samp {

Wrapper::Wrapper() {}

Wrapper *Wrapper::GetInstance() {
    static Wrapper w;
    return &w;
}

void Wrapper::Initialize(void **ppPluginData) {
    // Very important things
    ::pAMXFunctions = ppPluginData[PLUGIN_DATA_AMX_EXPORTS];
    ::logprintf = (logprintf_t)ppPluginData[PLUGIN_DATA_LOGPRINTF];

    // Hook amx_Register
    ::amx_Register_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_Register]);
    SetJump(reinterpret_cast<void*>(::amx_Register_addr), (void*)::my_amx_Register, ::amx_Register_code);

    // Hook amx_FindPublic
    ::amx_FindPublic_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_FindPublic]);
    SetJump(reinterpret_cast<void*>(::amx_FindPublic_addr), (void*)::my_amx_FindPublic, ::amx_FindPublic_code);

    // Hook amx_Exec
    ::amx_Exec_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_Exec]);
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::my_amx_Exec, ::amx_Exec_code);

    // Set handlers for all SA:MP callbacks
    samp::callbacks::InitializeCallbacks();
}

void Wrapper::SetNative(const std::string &name, AMX_NATIVE native) {
    if (!name.empty()) {
        natives_[name] = native;
    }
}

AMX_NATIVE Wrapper::GetNative(const std::string &name) const {
    std::map<std::string, AMX_NATIVE>::const_iterator it = natives_.find(name);
    if (it != natives_.end()) {
        return it->second;
    }
    return 0;
}

void Wrapper::SetPublicHandler(const std::string &name, PublicHandler handler) {
    publicHandlers_[name] = handler;
}

bool Wrapper::CallPublic(AMX *amx, cell *retval, const std::string &name) const {
    std::map<std::string, PublicHandler>::const_iterator it = publicHandlers_.find(name);
    if (it != publicHandlers_.end()) {
        *retval = it->second(amx);
        return true;
    }
    return false;
}

} // namespace samp
<commit_msg>Fix callbacks are called for only one plugin<commit_after>// Copyright (c) 2011 Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstring> // for memcpy()
#include <string>

#include "callbacks.h"
#include "jump.h"
#include "logprintf.h"
#include "wrapper.h"

#include "plugin/plugin.h"

#define AMX_EXEC_CHEAT (-10)

extern void *pAMXFunctions;

static uint32_t amx_Register_addr;
static unsigned char amx_Register_code[5];

static int my_amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, size_t number) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_Register_addr), ::amx_Register_code, 5);
    int error = amx_Register(amx, nativelist, number);

    // Store natives in our global container
    for (size_t i = 0; nativelist[i].name != 0 && (i < number || number == -1); ++i) {
        samp::Wrapper::GetInstance()->SetNative(nativelist[i].name, nativelist[i].func);
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_Register_addr), (void*)::my_amx_Register, ::amx_Register_code);

    return error;
}

static uint32_t amx_FindPublic_addr;
static unsigned char amx_FindPublic_code[5];

static AMX *pGamemode = 0;
static std::string lastPublicName;

static int my_amx_FindPublic(AMX *amx, const char *name, int *index) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_FindPublic_addr), ::amx_FindPublic_code, 5);
    int error = amx_FindPublic(amx, name, index);

    if (amx == ::pGamemode && ::pGamemode != 0) {
        if (error != AMX_ERR_NONE) {
            // The requested public doesn't exist but we say it does
            // to let the server subsequently execute it.
            *index = AMX_EXEC_CHEAT;
            error = AMX_ERR_NONE;
        }
        ::lastPublicName = name;
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_FindPublic_addr), (void*)::my_amx_FindPublic, ::amx_FindPublic_code);

    return error;
}

static uint32_t amx_Exec_addr;
static unsigned char amx_Exec_code[5];

static int my_amx_Exec(AMX *amx, cell *retval, int index) {
    // Restore the original code so we can call the function
    memcpy(reinterpret_cast<void*>(::amx_Exec_addr), ::amx_Exec_code, 5);

    if (index == AMX_EXEC_MAIN) {
        // main() is being called => this is the gamemode
        ::pGamemode = amx;
        // Manually call OnGameModeInit from here as it's usually called
        // before main() and is impossible to catch using the current method
        samp::Wrapper::GetInstance()->CallPublic(::pGamemode, retval, "OnGameModeInit");
    }

    if (amx == ::pGamemode && ::pGamemode != 0) {
        if (index != AMX_EXEC_MAIN && index != AMX_EXEC_CONT) {
            samp::Wrapper::GetInstance()->CallPublic(::pGamemode, retval, ::lastPublicName);
        }
    }

    int error = amx_Exec(amx, retval, index);
    if (index == AMX_EXEC_CHEAT) {
        error = AMX_ERR_NONE;
    }

    // Set the jump again to catch further calls
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::my_amx_Exec, ::amx_Exec_code);

    return error;
}

namespace samp {

Wrapper::Wrapper() {}

Wrapper *Wrapper::GetInstance() {
    static Wrapper w;
    return &w;
}

void Wrapper::Initialize(void **ppPluginData) {
    // Very important things
    ::pAMXFunctions = ppPluginData[PLUGIN_DATA_AMX_EXPORTS];
    ::logprintf = (logprintf_t)ppPluginData[PLUGIN_DATA_LOGPRINTF];

    // Hook amx_Register
    ::amx_Register_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_Register]);
    SetJump(reinterpret_cast<void*>(::amx_Register_addr), (void*)::my_amx_Register, ::amx_Register_code);

    // Hook amx_FindPublic
    ::amx_FindPublic_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_FindPublic]);
    SetJump(reinterpret_cast<void*>(::amx_FindPublic_addr), (void*)::my_amx_FindPublic, ::amx_FindPublic_code);

    // Hook amx_Exec
    ::amx_Exec_addr = reinterpret_cast<uint32_t>((static_cast<void**>(pAMXFunctions))[PLUGIN_AMX_EXPORT_Exec]);
    SetJump(reinterpret_cast<void*>(::amx_Exec_addr), (void*)::my_amx_Exec, ::amx_Exec_code);

    // Set handlers for all SA:MP callbacks
    samp::callbacks::InitializeCallbacks();
}

void Wrapper::SetNative(const std::string &name, AMX_NATIVE native) {
    if (!name.empty()) {
        natives_[name] = native;
    }
}

AMX_NATIVE Wrapper::GetNative(const std::string &name) const {
    std::map<std::string, AMX_NATIVE>::const_iterator it = natives_.find(name);
    if (it != natives_.end()) {
        return it->second;
    }
    return 0;
}

void Wrapper::SetPublicHandler(const std::string &name, PublicHandler handler) {
    publicHandlers_[name] = handler;
}

bool Wrapper::CallPublic(AMX *amx, cell *retval, const std::string &name) const {
    std::map<std::string, PublicHandler>::const_iterator it = publicHandlers_.find(name);
    if (it != publicHandlers_.end()) {
        *retval = it->second(amx);
        return true;
    }
    return false;
}

} // namespace samp
<|endoftext|>


<commit_before>/**
 * Game.cpp
 *
 *  Created on: Oct 31, 2013
 *      Authors: Eli Siskind & Kyle Despins
 */

#include "Game.h"

#include <cmath>
#include <iostream>
#include <assert.h>

#include "Bet.h"
#include "ComputerPlayer.h"
#include "Dealer.h"
#include "Deck.h"
#include "GameData.h"
#include "Gui.h"
#include "Hand.h"
#include "T2HumanPlayer.h"
#include "Player.h"
#include "PlayerList.h"
#include "SmallDeck.h"

using namespace std;

Game::Game() {
	state = NEWGAME;
	centerPot = 0;
	minBet = 20;
	numFolded = 0;
	showCompCards = true;
	button = NULL;
	winner = NULL;
	current = NULL;
	roundWinner = NULL;
	commCards = new SmallDeck();
	roundNum = 0;
	lastBet = Bet(INVALID, 0);
	cardsPlayed = 0;

}

Game::~Game() {

}

/*
 * Prompt user for a new game; if yes, create players and dealer.
 *
 * Player 1 is the human player, players 2 - 9 are computer.
 *
 * Returns true if a new game is started, and returns false otherwise.
 *
 */
bool Game::startGame(int startMoney) {

	// Make sure user wants to start a new game
	if (gui.startGui()) {

		// Dealer populates the deck
		dealer.makeDeck();

		// Create and add human player, make it the button
		T2HumanPlayer * human = new T2HumanPlayer(1, gui, startMoney); // Player 1
		playerList.add(human);
		button = human;

		// Make and add 8 computer players
		int i;
		for (i = 2; i <= 9; i++) {
			ComputerPlayer * computer = new ComputerPlayer(i);
			playerList.add(computer);
		}
		state = NEWGAME;
		return true; // Start a game
	}
	return false; // Don't start a game
}

/*
 * Plays another round if no one has one yet.
 *
 * Returns true if a new game is started, and returns false otherwise.
 *
 */
bool Game::playRound() {
	numFolded = 0;
	gui.newAd();
	if (newRound()) {
		if (!initialTurns()) {
			if (!flop()) {
				if (!turn()) {
					if (!river()) {
						updateGui(3);	// Show cards
						compareHands();
					}
				}
			}
		}
		return endRound();
	}

	return false;
}

/*
 * Checks if someone has won the game. If not, resets some variables for
 * a new round.
 *
 * First it sets the new min bet, then removes losers. If only one player
 * is left, they are the winner. Otherwise, state is set to 0, dealer shuffles
 * the deck, the round number is incremented, and the button is advanced.
 *
 *
 * Returns true if no one has won the game yet.
 */
bool Game::newRound() {

	bool gameOver;

	// Reset minBet. Doubles every five turns.
	minBet = (int) (20 * pow(2, floor(roundNum / 5)));

	// Remove the losers and advance the button
	purge();
	advanceButton();

	// Check if there is only one player left
	if (playerList.getSize() > 1) {

		// Reset everything for a new round
		state = NEWROUND;
		dealer.resetDeck();
		roundNum++;
		updateGui(0);
		button = playerList.next();
		gameOver = false;

	} else {
		winner = playerList.peek();
		gameOver = true;
	}
	return !gameOver;
}

bool Game::initialTurns() {

	//Start at the button
	goToButton();

	// Make big and little
	little();
	big();

	// Deal cards and bet
	givePlayerCards();
	return makeBets();

}

/*
 * Give each player a card, one at a time, and update the gui each time.
 */
void Game::givePlayerCards() {

	current = NULL;
	for (int i = 0; i < playerList.getSize() * 2; i++) {
		playerList.next()->giveCard(dealer.deal());
		updateGui(1);
	}
	cardsPlayed += 2;
}

void Game::little() {

	// Set current player and process their bet
	current = playerList.next();
	Bet bet = current->makeLittle(minBet);
	processBet(bet);

}

void Game::big() {

	// Set current player and process their bet
	current = playerList.next();
	Bet bet = current->makeBig(minBet);
	processBet(bet);

}

bool Game::flop() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = FLOP;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out three community cards
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);
	commCards->add(dealer.deal());
	updateGui(1);
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();

}

bool Game::turn() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = TURN;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out a community card
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();

}

bool Game::river() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = RIVER;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out a community card
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();
}

bool Game::makeBets() {
	Bet bet;

	// Each non-folded player makes a bet
	for (int i = 0; i < playerList.getSize(); i++) {

		current = playerList.next();
		updateGui(0);

		if (!current->isFolded()) {
			bet = current->makeBet(*commCards, minBet, state);
			processBet(bet);
			// If there is only one player left, the round is over
			if (numFolded > (playerList.getSize()) - 2) {
				while (playerList.peek()->isFolded()) {
					playerList.next();
				}
				roundWinner = playerList.peek();
				assert(roundWinner != NULL);
				assert(!roundWinner->isFolded());
				return true;
			}
		}
	}
	return false; // More than one player left
}

void Game::processBet(Bet bet) {

	// Fold the current player if their bet was to fold
	if (bet.getAction() == FOLD) {
		dealer.discard(current->fold());
		numFolded++;
	}

	// Add to the center pot, and change minimum bet if someone raised
	centerPot += bet.getAmount();
	minBet = minBet < bet.getAmount() ? bet.getAmount() : minBet;

	// Update the gui
	lastBet = bet;
	updateGui(2);
}
/*
 * Gives the roundwinner the pot, discards all the cards, and updates the GUI.
 */
bool Game::endRound() {

	if (gui.showRoundWinner(roundWinner->getNum(), centerPot, roundNum)) {
		roundWinner->takePot(centerPot);
		centerPot = 0;
		discardAll();
		updateGui(0);
		roundWinner = NULL;
		state = NEWROUND;
		return true;
	}
	return false;
}

/*
 * Compares the hands of each player, and sets roundWinner to
 * the player with the best hand
 */
void Game::compareHands() {

	Hand best;
	Hand temp;

	// First assume the first non folded player has the best hand
	current = playerList.peek();
	while (current->isFolded())
		current = playerList.next();
	roundWinner = current;
	best.evaluate(*current->getPocket(), *commCards);

	// Loop around the player list once and compare each hand
	for (int i = 0; i < playerList.getSize(); i++) {
		current = playerList.next();

		// only evaluate non-folded players
		if (!current->isFolded()) {

			// replace best if the current hand is better
			temp.evaluate(*current->getPocket(), *commCards);
			if (!(best > temp)) {
				best = temp;
				roundWinner = current;
			}
		}
	}
}

void Game::discardAll() {

	// Discard each player's pocket
	Player * start = playerList.peek();
	dealer.discard(playerList.peek()->getPocket());
	while (playerList.next() != start) {
		dealer.discard(playerList.peek()->getPocket());
	}

	// Discard community cards
	dealer.discard(commCards);
}

/*
 * Removes all players who cannot make the minimum bet, and adds their
 * money to the center pot.
 *
 * Returns true if the button has been removed.
 */
bool Game::purge() {
	int i;
	bool removedButton = false;
	Player * player = playerList.peek();	// Start at the first player
	int size = playerList.getSize();		// Save size since it changes

	// Loop around the player list once and remove players
	for (i = 0; i < size; i++) {
		//keep track of player money after bet
		if(player->isHuman())
				playerMoney = player->getMoney();
		if (player->getMoney() < minBet || player->getMoney() <= 0) {
			centerPot += player->getMoney();
			if (playerList.remove() == button) {	// advance the button
				removedButton = true;
				player = playerList.next();
				button = player;
			} else {
				player = playerList.next();
			}
		} else {
			player->unFold();
			player = playerList.next();
		}
	}

	return removedButton;
}

/*
 * Advances the button to the player after the current button.
 */
void Game::advanceButton() {

	// Go to the button
	goToButton();
	button = current;
}

/*
 * Advances the playerlist and until the button, and sets current to it.
 */
void Game::goToButton() {

	// Go to the button
	while (playerList.peek() != button)
		current = playerList.next();
}

//show winner and delete pointers for cards and players
int Game::endGame() {

	int humanMoney;

	// Show the winner
	if (winner != NULL) {
		gui.showWinner(winner->getNum());
	}
	// Remove players, discard their cards, and delete their pointers
	Player * player;
	while (playerList.peek() != NULL) {
		player = playerList.remove();
		if (player->getNum() == 1) {
			humanMoney = player->getMoney();
		}
		dealer.discard(player->getPocket());
		delete player;
	}

	// Discard community cards and delete all the card pointers
	dealer.discard(commCards);
	dealer.deleteAll();

	return humanMoney;
}

void Game::updateGui(int status) {

	// Update the game data object
	gameData.updateButton(button);
	gameData.updateCurrent(current);
	gameData.updatePlayers(playerList, (status == 3));
	gameData.updateCommunityCards(*commCards, state);
	gameData.setCenterPot(centerPot);
	gameData.setMinBet(minBet);
	gameData.setBet(lastBet);

	// Update the gui
	gui.update(gameData, status);

}
<commit_msg>pass money back to menu<commit_after>/**
 * Game.cpp
 *
 *  Created on: Oct 31, 2013
 *      Authors: Eli Siskind & Kyle Despins
 */

#include "Game.h"

#include <cmath>
#include <iostream>
#include <assert.h>

#include "Bet.h"
#include "ComputerPlayer.h"
#include "Dealer.h"
#include "Deck.h"
#include "GameData.h"
#include "Gui.h"
#include "Hand.h"
#include "T2HumanPlayer.h"
#include "Player.h"
#include "PlayerList.h"
#include "SmallDeck.h"

using namespace std;

Game::Game() {
	state = NEWGAME;
	centerPot = 0;
	minBet = 20;
	numFolded = 0;
	showCompCards = true;
	button = NULL;
	winner = NULL;
	current = NULL;
	roundWinner = NULL;
	commCards = new SmallDeck();
	roundNum = 0;
	lastBet = Bet(INVALID, 0);
	cardsPlayed = 0;

}

Game::~Game() {

}

/*
 * Prompt user for a new game; if yes, create players and dealer.
 *
 * Player 1 is the human player, players 2 - 9 are computer.
 *
 * Returns true if a new game is started, and returns false otherwise.
 *
 */
bool Game::startGame(int startMoney) {
	playerMoney = startMoney;
	// Make sure user wants to start a new game
	if (gui.startGui()) {

		// Dealer populates the deck
		dealer.makeDeck();

		// Create and add human player, make it the button
		T2HumanPlayer * human = new T2HumanPlayer(1, gui, startMoney); // Player 1
		playerList.add(human);
		button = human;

		// Make and add 8 computer players
		int i;
		for (i = 2; i <= 9; i++) {
			ComputerPlayer * computer = new ComputerPlayer(i);
			playerList.add(computer);
		}
		state = NEWGAME;
		return true; // Start a game
	}
	return false; // Don't start a game
}

/*
 * Plays another round if no one has one yet.
 *
 * Returns true if a new game is started, and returns false otherwise.
 *
 */
bool Game::playRound() {
	numFolded = 0;
	gui.newAd();
	if (newRound()) {
		if (!initialTurns()) {
			if (!flop()) {
				if (!turn()) {
					if (!river()) {
						updateGui(3);	// Show cards
						compareHands();
					}
				}
			}
		}
		return endRound();
	}

	return false;
}

/*
 * Checks if someone has won the game. If not, resets some variables for
 * a new round.
 *
 * First it sets the new min bet, then removes losers. If only one player
 * is left, they are the winner. Otherwise, state is set to 0, dealer shuffles
 * the deck, the round number is incremented, and the button is advanced.
 *
 *
 * Returns true if no one has won the game yet.
 */
bool Game::newRound() {

	bool gameOver;

	// Reset minBet. Doubles every five turns.
	minBet = (int) (20 * pow(2, floor(roundNum / 5)));

	// Remove the losers and advance the button
	purge();
	advanceButton();

	// Check if there is only one player left
	if (playerList.getSize() > 1) {

		// Reset everything for a new round
		state = NEWROUND;
		dealer.resetDeck();
		roundNum++;
		updateGui(0);
		button = playerList.next();
		gameOver = false;

	} else {
		winner = playerList.peek();
		gameOver = true;
	}
	return !gameOver;
}

bool Game::initialTurns() {

	//Start at the button
	goToButton();

	// Make big and little
	little();
	big();

	// Deal cards and bet
	givePlayerCards();
	return makeBets();

}

/*
 * Give each player a card, one at a time, and update the gui each time.
 */
void Game::givePlayerCards() {

	current = NULL;
	for (int i = 0; i < playerList.getSize() * 2; i++) {
		playerList.next()->giveCard(dealer.deal());
		updateGui(1);
	}
	cardsPlayed += 2;
}

void Game::little() {

	// Set current player and process their bet
	current = playerList.next();
	Bet bet = current->makeLittle(minBet);
	processBet(bet);

}

void Game::big() {

	// Set current player and process their bet
	current = playerList.next();
	Bet bet = current->makeBig(minBet);
	processBet(bet);

}

bool Game::flop() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = FLOP;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out three community cards
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);
	commCards->add(dealer.deal());
	updateGui(1);
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();

}

bool Game::turn() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = TURN;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out a community card
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();

}

bool Game::river() {

	minBet = 0;			// Players can check (AKA call 0) now
	state = RIVER;		// Update state
	goToButton();		// Make sure betting starts after the button

	// Dealer puts out a community card
	dealer.burn();
	commCards->add(dealer.deal());
	updateGui(1);

	// Make bets, returning true if there is a winner
	return makeBets();
}

bool Game::makeBets() {
	Bet bet;

	// Each non-folded player makes a bet
	for (int i = 0; i < playerList.getSize(); i++) {

		current = playerList.next();
		updateGui(0);

		if (!current->isFolded()) {
			bet = current->makeBet(*commCards, minBet, state);
			processBet(bet);
			// If there is only one player left, the round is over
			if (numFolded > (playerList.getSize()) - 2) {
				while (playerList.peek()->isFolded()) {
					playerList.next();
				}
				roundWinner = playerList.peek();
				assert(roundWinner != NULL);
				assert(!roundWinner->isFolded());
				return true;
			}
		}
	}
	return false; // More than one player left
}

void Game::processBet(Bet bet) {

	// Fold the current player if their bet was to fold
	if (bet.getAction() == FOLD) {
		dealer.discard(current->fold());
		numFolded++;
	}

	// Add to the center pot, and change minimum bet if someone raised
	centerPot += bet.getAmount();
	minBet = minBet < bet.getAmount() ? bet.getAmount() : minBet;

	// Update the gui
	lastBet = bet;
	updateGui(2);
}
/*
 * Gives the roundwinner the pot, discards all the cards, and updates the GUI.
 */
bool Game::endRound() {

	if (gui.showRoundWinner(roundWinner->getNum(), centerPot, roundNum)) {
		roundWinner->takePot(centerPot);
		centerPot = 0;
		discardAll();
		updateGui(0);
		roundWinner = NULL;
		state = NEWROUND;
		return true;
	}
	return false;
}

/*
 * Compares the hands of each player, and sets roundWinner to
 * the player with the best hand
 */
void Game::compareHands() {

	Hand best;
	Hand temp;

	// First assume the first non folded player has the best hand
	current = playerList.peek();
	while (current->isFolded())
		current = playerList.next();
	roundWinner = current;
	best.evaluate(*current->getPocket(), *commCards);

	// Loop around the player list once and compare each hand
	for (int i = 0; i < playerList.getSize(); i++) {
		current = playerList.next();

		// only evaluate non-folded players
		if (!current->isFolded()) {

			// replace best if the current hand is better
			temp.evaluate(*current->getPocket(), *commCards);
			if (!(best > temp)) {
				best = temp;
				roundWinner = current;
			}
		}
	}
}

void Game::discardAll() {

	// Discard each player's pocket
	Player * start = playerList.peek();
	dealer.discard(playerList.peek()->getPocket());
	while (playerList.next() != start) {
		dealer.discard(playerList.peek()->getPocket());
	}

	// Discard community cards
	dealer.discard(commCards);
}

/*
 * Removes all players who cannot make the minimum bet, and adds their
 * money to the center pot.
 *
 * Returns true if the button has been removed.
 */
bool Game::purge() {
	int i;
	bool removedButton = false;
	Player * player = playerList.peek();	// Start at the first player
	int size = playerList.getSize();		// Save size since it changes

	// Loop around the player list once and remove players
	for (i = 0; i < size; i++) {
		//keep track of player money after bet
		if(player->isHuman())
				playerMoney = player->getMoney();
		if (player->getMoney() < minBet || player->getMoney() <= 0) {
			centerPot += player->getMoney();
			if (playerList.remove() == button) {	// advance the button
				removedButton = true;
				player = playerList.next();
				button = player;
			} else {
				player = playerList.next();
			}
		} else {
			player->unFold();
			player = playerList.next();
		}
	}

	return removedButton;
}

/*
 * Advances the button to the player after the current button.
 */
void Game::advanceButton() {

	// Go to the button
	goToButton();
	button = current;
}

/*
 * Advances the playerlist and until the button, and sets current to it.
 */
void Game::goToButton() {

	// Go to the button
	while (playerList.peek() != button)
		current = playerList.next();
}

//show winner and delete pointers for cards and players
int Game::endGame() {

	int humanMoney;

	// Show the winner
	if (winner != NULL) {
		gui.showWinner(winner->getNum());
	}
	// Remove players, discard their cards, and delete their pointers
	Player * player;
	while (playerList.peek() != NULL) {
		player = playerList.remove();
		if (player->getNum() == 1) {
			humanMoney = player->getMoney();
		}
		dealer.discard(player->getPocket());
		delete player;
	}

	// Discard community cards and delete all the card pointers
	dealer.discard(commCards);
	dealer.deleteAll();

	return humanMoney;
}

void Game::updateGui(int status) {

	// Update the game data object
	gameData.updateButton(button);
	gameData.updateCurrent(current);
	gameData.updatePlayers(playerList, (status == 3));
	gameData.updateCommunityCards(*commCards, state);
	gameData.setCenterPot(centerPot);
	gameData.setMinBet(minBet);
	gameData.setBet(lastBet);

	// Update the gui
	gui.update(gameData, status);

}
<|endoftext|>


<commit_before>#include <vector>
#include <iostream>
#include <string>
#include "FileSystem.h"
using namespace std;

#define MAX_STRING 100 // Disk of 10 blocks, of size 10 chars
#define MAX_ARGS 2

vector<string> splitbystring(string , string );
int main(){
	char userInput[MAX_STRING];
	char ch;
	bool cont = true;
	string input;
	string typeInput;
	vector<string> args;

	FileSystem acmeFS;

	while (cont){
		cout << "$$";
		getline(cin, input);
		args = splitbystring(input, " ");
		for (int i = 0; i < args.size(); i++){
			cout << i << ": " << args[i] << endl;
		}

		if (args[0] == "EXIT"){
			cont = false;
		}else if (args[0] == "DIR") {
			acmeFS.printDir();
		if (input.find_first_not_of(" \t\n\v\f\r") != std::string::npos && (!cin.eof())){
			args = splitbystring(input, " ");
			for (int i = 0; i < args.size(); i++){
				cout << i << ": " << args[i] << endl;
			}
			if (args[0] == "EXIT"){
				cont = false;
			}
			else if (args[0] == "CREATE"){

			}
			else if (args[0] == "TYPE"){
				memset(userInput, 0, MAX_STRING);
				cout << endl;

				while(!cin.eof()){
					getline(cin, typeInput);
				}
				//while(EOF != scanf("%s", userInput));
	    		cout << endl;
	    		cout << "TYPEINPUT " << typeInput << endl;
	    		//printf("YOU INPUT: %s\n", userInput);

		}
		else if(args.size() == 2) {
			if (args[0] == "CREATE") {
				acmeFS.create(args[1]);

			} else if (args[0] == "TYPE") {
				acmeFS.read(args[1]);

			}

		}

		else{
			cout << "Invalid\n";
		}
	}

}
vector<string> splitbystring(string token, string delim){
	int left = 0;
	vector<string>ret_vec;
	std::size_t found = token.find(delim);

	if (found > token.size() + 1){
		ret_vec.push_back(token);
		return ret_vec;
	}
	cout << "found = " << found << endl;
	if(found != std::string::npos){
		ret_vec.push_back(token.substr(left, found-left));
		left = found+delim.size();
	}
	while(found != std::string::npos){
		found = token.find(delim, found+1);
		ret_vec.push_back(token.substr(left, found-left));
		left = found+delim.size();
	}
	return ret_vec;
}
<commit_msg>--CBP<commit_after>#include <vector>
#include <iostream>
#include <string>
#include "FileSystem.h"
using namespace std;

#define MAX_STRING 100 // Disk of 10 blocks, of size 10 chars
#define MAX_ARGS 2

vector<string> splitbystring(string , string );
int main(){
	char userInput[MAX_STRING];
	char ch;
	bool cont = true;
	string input;
	string typeInput;
	vector<string> args;

	FileSystem acmeFS;

	while (cont){
		cout << "$$";
		getline(cin, input);
		args = splitbystring(input, " ");
		for (int i = 0; i < args.size(); i++){
			cout << i << ": " << args[i] << endl;
		}

		if (input.find_first_not_of(" \t\n\v\f\r") != std::string::npos && (!cin.eof())){

            args = splitbystring(input, " ");
			for (int i = 0; i < args.size(); i++){
				cout << i << ": " << args[i] << endl;
			}

			if(args[0] == "EXIT"){
				cont = false;
            } else if (args[0] == "DIR") {
                acmeFS.printDir();
            }
		}
		else if(args.size() == 2) {
			if (args[0] == "CREATE") {
				acmeFS.create(args[1]);

			} else if (args[0] == "TYPE") {
//                memset(userInput, 0, MAX_STRING);
                cout << endl;

                while(!cin.eof()){
                    getline(cin, typeInput);
                }
                //while(EOF != scanf("%s", userInput));
                cout << endl;
                cout << "TYPEINPUT " << typeInput << endl;
                //printf("YOU INPUT: %s\n", userInput);

                acmeFS.read(args[1]);
			}

		}

		else{
			cout << "Invalid\n";
		}
	}

}
vector<string> splitbystring(string token, string delim){
	int left = 0;
	vector<string>ret_vec;
	std::size_t found = token.find(delim);

	if (found > token.size() + 1){
		ret_vec.push_back(token);
		return ret_vec;
	}
	cout << "found = " << found << endl;
	if(found != std::string::npos){
		ret_vec.push_back(token.substr(left, found-left));
		left = found+delim.size();
	}
	while(found != std::string::npos){
		found = token.find(delim, found+1);
		ret_vec.push_back(token.substr(left, found-left));
		left = found+delim.size();
	}
	return ret_vec;
}
<|endoftext|>


<commit_before><commit_msg>[REFACT] Fixed bound import description<commit_after><|endoftext|>


<commit_before><commit_msg>feeder: Fix mmap() arguments on x86_64.<commit_after><|endoftext|>