C++ [Microsoft][ODBC SQL Server Driver]String data, right truncation - c++

I need help with ODBC prepared queries. I working on Windows 10(x64). My VPS server is Windows Server 2012(x64). My compiled aplication is 32 bit. I need prepared queries to make SQL Injection not possible. But have one big problem.
Error:
[QueryManager] State (22001), Diagnostic: [Microsoft][ODBC SQL Server Driver]String data, right truncation
Code:
gQueryManager.BindParameterAsString(1,Name,sizeof(Name));
gQueryManager.ExecQuery("SELECT Value FROM Table WHERE Name=?");
gQueryManager.Fetch();
...
gQueryManager.Close();
This is source code of Query Manager I using:
// QueryManager.cpp: implementation of the CQueryManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "QueryManager.h"
#include "Util.h"
CQueryManager gQueryManager;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CQueryManager::CQueryManager() // OK
{
this->m_SQLEnvironment = SQL_NULL_HANDLE;
this->m_SQLConnection = SQL_NULL_HANDLE;
this->m_STMT = SQL_NULL_HANDLE;
this->m_RowCount = -1;
this->m_ColCount = -1;
memset(this->m_SQLColName,0,sizeof(this->m_SQLColName));
memset(this->m_SQLData,0,sizeof(this->m_SQLData));
SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&this->m_SQLEnvironment);
SQLSetEnvAttr(this->m_SQLEnvironment,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER);
}
CQueryManager::~CQueryManager() // OK
{
this->Disconnect();
}
bool CQueryManager::Connect(char* odbc,char* user,char* pass) // OK
{
strcpy_s(this->m_odbc,odbc);
strcpy_s(this->m_user,user);
strcpy_s(this->m_pass,pass);
if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC,this->m_SQLEnvironment,&this->m_SQLConnection)) == 0)
{
return 0;
}
if(SQL_SUCCEEDED(SQLConnect(this->m_SQLConnection,(SQLCHAR*)this->m_odbc,SQL_NTS,(SQLCHAR*)this->m_user,SQL_NTS,(SQLCHAR*)this->m_pass,SQL_NTS)) == 0)
{
return 0;
}
if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT,this->m_SQLConnection,&this->m_STMT)) == 0)
{
return 0;
}
else
{
return 1;
}
}
void CQueryManager::Disconnect() // OK
{
if(this->m_STMT != SQL_NULL_HANDLE)
{
SQLFreeHandle(SQL_HANDLE_STMT,this->m_STMT);
this->m_STMT = SQL_NULL_HANDLE;
}
if(this->m_SQLConnection != SQL_NULL_HANDLE)
{
SQLFreeHandle(SQL_HANDLE_DBC,this->m_SQLConnection);
this->m_SQLConnection = SQL_NULL_HANDLE;
}
if(this->m_SQLEnvironment != SQL_NULL_HANDLE)
{
SQLFreeHandle(SQL_HANDLE_ENV,this->m_SQLEnvironment);
this->m_SQLEnvironment = SQL_NULL_HANDLE;
}
}
void CQueryManager::Diagnostic(char* query) // OK
{
LogAdd(LOG_BLACK,"%s",query);
SQLINTEGER NativeError;
SQLSMALLINT RecNumber=1,BufferLength;
SQLCHAR SqlState[6],MessageText[SQL_MAX_MESSAGE_LENGTH];
while(SQLGetDiagRec(SQL_HANDLE_STMT,this->m_STMT,(RecNumber++),SqlState,&NativeError,MessageText,sizeof(MessageText),&BufferLength) != SQL_NO_DATA)
{
LogAdd(LOG_RED,"[QueryManager] State (%s), Diagnostic: %s",SqlState,MessageText);
}
if(strcmp((char*)SqlState,"08S01") == 0)
{
this->Connect(this->m_odbc,this->m_user,this->m_pass);
}
}
bool CQueryManager::ExecQuery(char* query,...) // OK
{
char buff[4096];
va_list arg;
va_start(arg,query);
vsprintf_s(buff,query,arg);
va_end(arg);
SQLRETURN result;
if(SQL_SUCCEEDED((result=SQLExecDirect(this->m_STMT,(SQLCHAR*)buff,SQL_NTS))) == 0 && result != SQL_NO_DATA)
{
this->Diagnostic(buff);
return 0;
}
SQLRowCount(this->m_STMT,&this->m_RowCount);
if(this->m_RowCount == 0){return 1;}
SQLNumResultCols(this->m_STMT,&this->m_ColCount);
if(this->m_ColCount == 0){return 1;}
if(this->m_ColCount > MAX_COLUMNS){return 0;}
memset(this->m_SQLColName,0,sizeof(this->m_SQLColName));
memset(this->m_SQLData,0,sizeof(this->m_SQLData));
for(int n=0;n < this->m_ColCount;n++)
{
SQLDescribeCol(this->m_STMT,(n+1),this->m_SQLColName[n],sizeof(this->m_SQLColName[n]),0,0,0,0,0);
SQLBindCol(this->m_STMT,(n+1),SQL_C_CHAR,this->m_SQLData[n],sizeof(this->m_SQLData[n]),&this->m_SQLDataLen[n]);
}
return 1;
}
void CQueryManager::Close() // OK
{
SQLCloseCursor(this->m_STMT);
SQLFreeStmt(this->m_STMT,SQL_UNBIND);
}
SQLRETURN CQueryManager::Fetch() // OK
{
return SQLFetch(this->m_STMT);
}
int CQueryManager::FindIndex(char* ColName) // OK
{
for(int n=0;n < this->m_ColCount;n++)
{
if(_stricmp(ColName,(char*)this->m_SQLColName[n]) == 0)
{
return n;
}
}
return -1;
}
int CQueryManager::GetResult(int index) // OK
{
return atoi(this->m_SQLData[index]);
}
int CQueryManager::GetAsInteger(char* ColName) // OK
{
int index = this->FindIndex(ColName);
if(index == -1)
{
return index;
}
else
{
return atoi(this->m_SQLData[index]);
}
}
float CQueryManager::GetAsFloat(char* ColName) // OK
{
int index = this->FindIndex(ColName);
if(index == -1)
{
return (float)index;
}
else
{
return (float)atof(this->m_SQLData[index]);
}
}
__int64 CQueryManager::GetAsInteger64(char* ColName) // OK
{
int index = this->FindIndex(ColName);
if(index == -1)
{
return index;
}
else
{
return _atoi64(this->m_SQLData[index]);
}
}
void CQueryManager::GetAsString(char* ColName,char* OutBuffer,int OutBufferSize) // OK
{
int index = this->FindIndex(ColName);
if(index == -1)
{
memset(OutBuffer,0,OutBufferSize);
}
else
{
strncpy_s(OutBuffer,OutBufferSize,this->m_SQLData[index],(OutBufferSize-1));
}
}
void CQueryManager::GetAsBinary(char* ColName,BYTE* OutBuffer,int OutBufferSize) // OK
{
int index = this->FindIndex(ColName);
if(index == -1)
{
memset(OutBuffer,0,OutBufferSize);
}
else
{
this->ConvertStringToBinary(this->m_SQLData[index],sizeof(this->m_SQLData[index]),OutBuffer,OutBufferSize);
}
}
void CQueryManager::BindParameterAsString(int ParamNumber,void* InBuffer,int ColumnSize) // OK
{
this->m_SQLBindValue[(ParamNumber-1)] = SQL_NTS;
SQLBindParameter(this->m_STMT,ParamNumber,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR,ColumnSize,0,InBuffer,0,&this->m_SQLBindValue[(ParamNumber-1)]);
}
void CQueryManager::BindParameterAsBinary(int ParamNumber,void* InBuffer,int ColumnSize) // OK
{
this->m_SQLBindValue[(ParamNumber-1)] = ColumnSize;
SQLBindParameter(this->m_STMT,ParamNumber,SQL_PARAM_INPUT,SQL_C_BINARY,SQL_VARBINARY,ColumnSize,0,InBuffer,0,&this->m_SQLBindValue[(ParamNumber-1)]);
}
void CQueryManager::ConvertStringToBinary(char* InBuff,int InSize,BYTE* OutBuff,int OutSize) // OK
{
int size = 0;
memset(OutBuff,0,OutSize);
for(int n=0;n < InSize,size < OutSize;n++)
{
if(InBuff[n] == 0)
{
break;
}
if((n%2) == 0)
{
OutBuff[size] = ((InBuff[n]>='A')?((InBuff[n]-'A')+10):(InBuff[n]-'0'))*16;
size = size+0;
}
else
{
OutBuff[size] = OutBuff[size] | ((InBuff[n]>='A')?((InBuff[n]-'A')+10):(InBuff[n]-'0'));
size = size+1;
}
}
}
void CQueryManager::ConvertBinaryToString(BYTE* InBuff,int InSize,char* OutBuff,int OutSize) // OK
{
int size = 0;
memset(OutBuff,0,OutSize);
for(int n=0;n < OutSize,size < InSize;n++)
{
if((n%2) == 0)
{
OutBuff[n] = (((InBuff[size]/16)>=10)?('A'+((InBuff[size]/16)-10)):('0'+(InBuff[size]/16)));
size = size+0;
}
else
{
OutBuff[n] = (((InBuff[size]%16)>=10)?('A'+((InBuff[size]%16)-10)):('0'+(InBuff[size]%16)));
size = size+1;
}
}
}

Related

Memory change detection function in C++ isn't detecting properly some malwares

I'm having an anti cheat system for my private online game platformed for Windows.
One of the most popular functions I have is memory change detection.
Source code for memory change detections:
bool MEMORY_PROTECTION_INIT() // OK
{
bool ClearFileMapping = 0;
if((FileMappingHandle=CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,sizeof(HACK_VERIFY_FILE_MAPPING),"Local\\HACK_VERIFY_FILE_MAPPING")) == 0)
{
return 0;
}
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
ClearFileMapping = 0;
}
else
{
ClearFileMapping = 1;
}
if((lpHackVerifyFileMapping=(HACK_VERIFY_FILE_MAPPING*)MapViewOfFile(FileMappingHandle,FILE_MAP_ALL_ACCESS,0,0,sizeof(HACK_VERIFY_FILE_MAPPING))) == 0)
{
return 0;
}
if(ClearFileMapping != 0)
{
lpHackVerifyFileMapping->Clear();
}
MemoryProtectionTime = GetTickCount();
return 1;
}
bool MEMORY_PROTECTION_SCAN() // OK
{
if(gMemoryGuardSwitch == 0 || (gMemoryGuardNumber & MEMORY_GUARD_NUMBER_INJECT) == 0)
{
return 1;
}
for(DWORD n=0;n < lpHackVerifyFileMapping->WriteVirtualMemoryCount;n++)
{
HACK_VERIFY_FILE* lpHackVerifyFile = &lpHackVerifyFileMapping->WriteVirtualMemoryTable[n];
if(lpHackVerifyFile->time >= MemoryProtectionTime)
{
if(lpHackVerifyFile->spid != GetCurrentProcessId())
{
if(lpHackVerifyFile->tpid == GetCurrentProcessId())
{
CHClientDisconnectSend(CLIENT_DISCONNECT_MEMORY_DETECTION,0,lpHackVerifyFile->spid);
return 1;
}
}
}
}
return 1;
}
bool HANDLE_PROTECTION_INIT() // OK
{
CProcessQuery ProcessQuery;
HANDLE HandleValue = OpenProcess(PROCESS_VM_READ,0,GetCurrentProcessId());
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId == GetCurrentProcessId() && lpSystemHandleEntryInfo->HandleValue == ((DWORD)HandleValue))
{
HandleProtectionNumber = (DWORD)lpSystemHandleEntryInfo->ObjectTypeIndex;
HandleProtectionObject = (DWORD)lpSystemHandleEntryInfo->Object;
ProcessQuery.Close();
return 1;
}
}
}
}
}
ProcessQuery.Close();
return 0;
}
bool HANDLE_PROTECTION_SCAN() // OK
{
if(gMemoryGuardSwitch == 0 || (gMemoryGuardNumber & MEMORY_GUARD_NUMBER_HANDLE) == 0)
{
return 1;
}
static CProcessQuery ProcessQuery;
std::map<DWORD,std::vector<DWORD>> HandleProtectionTable;
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId != GetCurrentProcessId() && lpSystemHandleEntryInfo->ObjectTypeIndex == HandleProtectionNumber && lpSystemHandleEntryInfo->Object == ((LPVOID)HandleProtectionObject) && (lpSystemHandleEntryInfo->GrantedAccess & PROCESS_VM_WRITE) != 0)
{
std::map<DWORD,std::vector<DWORD>>::iterator it = HandleProtectionTable.find(lpSystemHandleEntryInfo->UniqueProcessId);
if(it == HandleProtectionTable.end())
{
HandleProtectionTable.insert(std::pair<DWORD,std::vector<DWORD>>(lpSystemHandleEntryInfo->UniqueProcessId,std::vector<DWORD>(1,lpSystemHandleEntryInfo->HandleValue)));
continue;
}
else
{
if(it->second.size() >= 10)
{
CHClientDisconnectSend(CLIENT_DISCONNECT_MEMORY_DETECTION,0,lpSystemHandleEntryInfo->UniqueProcessId);
return 0;
}
else
{
it->second.push_back(lpSystemHandleEntryInfo->HandleValue);
continue;
}
}
}
}
}
}
}
return 1;
}
bool MEMORY_CHECK_ATTACH() // OK
{
CCRC32 CRC32;
MODULEINFO ModuleInfo;
memset(&ModuleInfo,0,sizeof(ModuleInfo));
if(GetModuleInformation(GetCurrentProcess(),GetModuleHandle(0),&ModuleInfo,sizeof(ModuleInfo)) == 0)
{
return 0;
}
IMAGE_NT_HEADERS32* lpNtHeader = (IMAGE_NT_HEADERS32*)((DWORD)ModuleInfo.lpBaseOfDll+((IMAGE_DOS_HEADER*)ModuleInfo.lpBaseOfDll)->e_lfanew);
IMAGE_SECTION_HEADER* lpSectionHeader = (IMAGE_SECTION_HEADER*)((DWORD)lpNtHeader+sizeof(IMAGE_NT_HEADERS32));
for(int n=0;n < lpNtHeader->FileHeader.NumberOfSections;n++)
{
MEMORY_CHECK_SOURCE data;
data.VirtualAddress = (DWORD)ModuleInfo.lpBaseOfDll+lpSectionHeader[n].VirtualAddress;
data.VirtualSize = lpSectionHeader[n].Misc.VirtualSize;
data.VirtualChecksum = CRC32.FullCRC((BYTE*)data.VirtualAddress,data.VirtualSize);
MemoryCheckSource.insert(std::pair<DWORD,MEMORY_CHECK_SOURCE>(data.VirtualAddress,data));
break;
}
return 1;
}
bool MEMORY_CHECK_DETACH() // OK
{
CCRC32 CRC32;
for(std::map<DWORD,MEMORY_CHECK_SOURCE>::iterator it=MemoryCheckSource.begin();it != MemoryCheckSource.end();it++)
{
if(it->second.VirtualChecksum != CRC32.FullCRC((BYTE*)it->second.VirtualAddress,it->second.VirtualSize))
{
return 0;
}
}
return 1;
}
For some reasons it works fine on some malwares, but some software (that are doing memory changes too) aren't detected by the function.
After few checks I realized that the difference between both types of cheats is the memory base address.
For those that are detected by the function- the base address that is calling to Heap(id2) is 0x30000. Although the software that aren't detected by the function- the base address that is calling to heap(id2) (- same use) is 0x10000 (the first one).
any ideas what changes should I make to make sure that these cheats are blocked?

error C2664: cannot convert argument 1 from 'NvPhysicalGpuHandle'

I'm trying to add Nvidia API into kodi for HDR switching.
I don't have much knowledge of code, I'm trying to adapt a project HDR Switcher into kodi functions.
When compiling the HDR Switcher into an exe with visual studio it works and triggers HDR.
Now I need to make it work with kodi for seamless HDR pasthrough playback.
This uses the NVidia private APIs.
Please help this will be valuable for many users if it gets implemented.
The error:
error C2664: 'NvAPI_St
atus NvAPI_GPU_GetConnectedDisplayIds(NvPhysicalGpuHandle,NV_GPU_DISPLAYIDS *,NvU32 *,NvU32)': cannot convert argument
1 from 'NvPhysicalGpuHandle [64]' to 'NvPhysicalGpuHandle'
#include "WinRenderer.h"
#include "RenderCapture.h"
#include "RenderFactory.h"
#include "RenderFlags.h"
#include "rendering/dx/RenderContext.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/log.h"
#include "windows/RendererDXVA.h"
#include "windows/RendererSoftware.h"
#include "windows/RendererShaders.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinSystem.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "DeviceManager.h"
#include "nvapi.h"
#include "uhdDisplay.h"
struct render_details
{
using map = std::map<RenderMethod, int>;
using weights_fn = std::function<void(map&, const VideoPicture&)>;
using create_fn = std::function<CRendererBase*(CVideoSettings&)>;
RenderMethod method;
std::string name;
create_fn create;
weights_fn weights;
template<class T>
constexpr static render_details get(RenderMethod method, const std::string& name)
{
return { method, name, T::Create, T::GetWeight };
}
};
static std::vector<render_details> RenderMethodDetails =
{
render_details::get<CRendererSoftware>(RENDER_SW, "Software"),
render_details::get<CRendererShaders>(RENDER_PS, "Pixel Shaders"),
render_details::get<CRendererDXVA>(RENDER_DXVA, "DXVA"),
};
CBaseRenderer* CWinRenderer::Create(CVideoBuffer*)
{
return new CWinRenderer();
}
bool CWinRenderer::Register()
{
VIDEOPLAYER::CRendererFactory::RegisterRenderer("default", Create);
return true;
}
CWinRenderer::CWinRenderer()
{
m_format = AV_PIX_FMT_NONE;
PreInit();
}
CWinRenderer::~CWinRenderer()
{
CWinRenderer::UnInit();
}
CRendererBase* CWinRenderer::SelectRenderer(const VideoPicture& picture)
{
int iRequestedMethod = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_VIDEOPLAYER_RENDERMETHOD);
CLog::LogF(LOGDEBUG, "requested render method: %d", iRequestedMethod);
std::map<RenderMethod, int> weights;
for (auto& details : RenderMethodDetails)
details.weights(weights, picture);
RenderMethod method;
switch (iRequestedMethod)
{
case RENDER_METHOD_SOFTWARE:
if (weights[RENDER_SW])
{
method = RENDER_SW;
break;
}
// fallback to PS
case RENDER_METHOD_D3D_PS:
if (weights[RENDER_PS])
{
method = RENDER_PS;
break;
}
//fallback to DXVA
case RENDER_METHOD_DXVA:
if (weights[RENDER_DXVA])
{
method = RENDER_DXVA;
break;
}
// fallback to AUTO
case RENDER_METHOD_AUTO:
default:
{
const auto it = std::max_element(weights.begin(), weights.end(),
[](auto& w1, auto& w2) { return w1.second < w2.second; });
if (it != weights.end())
{
method = it->first;
break;
}
// there is no elements in weights, so no renderer which supports incoming video buffer
CLog::LogF(LOGERROR, "unable to select render method for video buffer");
return nullptr;
}
}
const auto it = std::find_if(RenderMethodDetails.begin(), RenderMethodDetails.end(),
[method](render_details& d) { return d.method == method; });
if (it != RenderMethodDetails.end())
{
CLog::LogF(LOGDEBUG, "selected render method: {}", it->name);
return it->create(m_videoSettings);
}
// something goes really wrong
return nullptr;
}
CRect CWinRenderer::GetScreenRect() const
{
CRect screenRect(0.f, 0.f,
static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()),
static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()));
switch (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode())
{
case RENDER_STEREO_MODE_SPLIT_HORIZONTAL:
screenRect.y2 *= 2;
break;
case RENDER_STEREO_MODE_SPLIT_VERTICAL:
screenRect.x2 *= 2;
break;
default:
break;
}
return screenRect;
}
bool CWinRenderer::Configure(const VideoPicture &picture, float fps, unsigned int orientation)
{
m_sourceWidth = picture.iWidth;
m_sourceHeight = picture.iHeight;
m_renderOrientation = orientation;
m_fps = fps;
m_iFlags = GetFlagsChromaPosition(picture.chroma_position)
| GetFlagsColorMatrix(picture.color_space, picture.iWidth, picture.iHeight)
| GetFlagsColorPrimaries(picture.color_primaries)
| GetFlagsStereoMode(picture.stereoMode);
m_format = picture.videoBuffer->GetFormat();
// calculate the input frame aspect ratio
CalculateFrameAspectRatio(picture.iDisplayWidth, picture.iDisplayHeight);
SetViewMode(m_videoSettings.m_ViewMode);
// if (picture.hasDisplayMetadata || picture.hasLightMetadata) {
SetHdrMonitorMode(true);
// }
ManageRenderArea();
m_renderer.reset(SelectRenderer(picture));
if (!m_renderer || !m_renderer->Configure(picture, fps, orientation))
{
m_renderer.reset();
return false;
}
m_bConfigured = true;
return true;
}
static bool first = true;
void CWinRenderer::SetHdrMonitorMode(bool enableHDR)
{
if (first)
{
NvAPI_Initialize();
first = false;
}
NvAPI_Status nvStatus = NVAPI_OK;
NvDisplayHandle hNvDisplay = NULL;
// get first display handle which should work for all NVAPI calls for all GPUs
if ((nvStatus = NvAPI_EnumNvidiaDisplayHandle(0, &hNvDisplay)) != NVAPI_OK)
{
printf("NvAPI_EnumNvidiaDisplayHandle returned error code %d\r\n", nvStatus);
return;
}
NvU32 gpuCount = 0;
NvU32 maxDisplayIndex = 0;
NvPhysicalGpuHandle ahGPU[NVAPI_MAX_PHYSICAL_GPUS] = {};
// get the list of displays connected, populate the dynamic components
nvStatus = NvAPI_EnumPhysicalGPUs(ahGPU, &gpuCount);
if (NVAPI_OK != nvStatus)
{
printf("NvAPI_EnumPhysicalGPUs returned error code %d\r\n", nvStatus);
return;
}
for (NvU32 i = 0; i < gpuCount; ++i)
{
NvU32 displayIdCount = 16;
NvU32 flags = 0;
NV_GPU_DISPLAYIDS displayIdArray[16] = {};
displayIdArray[0].version = NV_GPU_DISPLAYIDS_VER;
nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU, displayIdArray, &displayIdCount, flags);
if (NVAPI_OK == nvStatus)
{
printf("Display count %d\r\n", displayIdCount);
for (maxDisplayIndex = 0; maxDisplayIndex < displayIdCount; ++maxDisplayIndex)
{
printf("Display tested %d\r\n", maxDisplayIndex);
NV_HDR_CAPABILITIES hdrCapabilities = {};
hdrCapabilities.version = NV_HDR_CAPABILITIES_VER;
if (NVAPI_OK == NvAPI_Disp_GetHdrCapabilities(displayIdArray[maxDisplayIndex].displayId, &hdrCapabilities))
{
if (hdrCapabilities.isST2084EotfSupported)
{
printf("Display %d supports ST2084 EOTF\r\n", maxDisplayIndex);
NV_HDR_COLOR_DATA hdrColorData = {};
memset(&hdrColorData, 0, sizeof(hdrColorData));
hdrColorData.version = NV_HDR_COLOR_DATA_VER;
hdrColorData.cmd = NV_HDR_CMD_SET;
hdrColorData.static_metadata_descriptor_id = NV_STATIC_METADATA_TYPE_1;
hdrColorData.hdrMode = enableHDR ? NV_HDR_MODE_UHDBD : NV_HDR_MODE_OFF;
nvStatus = NvAPI_Disp_HdrColorControl(displayIdArray[maxDisplayIndex].displayId, &hdrColorData);
if (NVAPI_OK == nvStatus)
{
printf("NvAPI_Disp_SethdrColorData call has succeeded: ");
}
else
{
NvAPI_ShortString szDesc;
NvAPI_GetErrorMessage(nvStatus, szDesc);
printf("NvAPI_Disp_HdrColorControl returned %s (%x)\r\n", szDesc, nvStatus);
}
}
}
else
{
NvAPI_ShortString szDesc;
NvAPI_GetErrorMessage(nvStatus, szDesc);
printf("NvAPI_Disp_GetHdrCapabilities returned %s (%x)\r\n", szDesc, nvStatus);
}
}
}
else
{
NvAPI_ShortString szDesc;
NvAPI_GetErrorMessage(nvStatus, szDesc);
printf("NvAPI_GPU_GetConnectedDisplayIds returned %s (%x)\r\n", szDesc, nvStatus);
}
}
}
int CWinRenderer::NextBuffer() const
{
return m_renderer->NextBuffer();
}
void CWinRenderer::AddVideoPicture(const VideoPicture &picture, int index)
{
m_renderer->AddVideoPicture(picture, index);
}
void CWinRenderer::Update()
{
if (!m_bConfigured)
return;
ManageRenderArea();
m_renderer->ManageTextures();
}
void CWinRenderer::RenderUpdate(int index, int index2, bool clear, unsigned int flags, unsigned int alpha)
{
if (!m_bConfigured)
return;
if (clear)
CServiceBroker::GetWinSystem()->GetGfxContext().Clear(DX::Windowing()->UseLimitedColor() ? 0x101010 : 0);
DX::Windowing()->SetAlphaBlendEnable(alpha < 255);
ManageRenderArea();
m_renderer->Render(index, index2, DX::Windowing()->GetBackBuffer(),
m_sourceRect, m_destRect, GetScreenRect(), flags);
}
bool CWinRenderer::RenderCapture(CRenderCapture* capture)
{
if (!m_bConfigured)
return false;
capture->BeginRender();
if (capture->GetState() != CAPTURESTATE_FAILED)
{
const CRect destRect(0, 0, static_cast<float>(capture->GetWidth()), static_cast<float>(capture->GetHeight()));
m_renderer->Render(capture->GetTarget(), m_sourceRect, destRect, GetScreenRect());
capture->EndRender();
return true;
}
return false;
}
void CWinRenderer::SetBufferSize(int numBuffers)
{
if (!m_bConfigured)
return;
m_renderer->SetBufferSize(numBuffers);
}
void CWinRenderer::PreInit()
{
CSingleLock lock(CServiceBroker::GetWinSystem()->GetGfxContext());
m_bConfigured = false;
UnInit();
}
void CWinRenderer::UnInit()
{
CSingleLock lock(CServiceBroker::GetWinSystem()->GetGfxContext());
m_renderer.reset();
m_bConfigured = false;
}
bool CWinRenderer::Flush(bool saveBuffers)
{
if (!m_bConfigured)
return false;
return m_renderer->Flush(saveBuffers);
}
bool CWinRenderer::Supports(ERENDERFEATURE feature)
{
if(feature == RENDERFEATURE_BRIGHTNESS)
return true;
if(feature == RENDERFEATURE_CONTRAST)
return true;
if (feature == RENDERFEATURE_STRETCH ||
feature == RENDERFEATURE_NONLINSTRETCH ||
feature == RENDERFEATURE_ZOOM ||
feature == RENDERFEATURE_VERTICAL_SHIFT ||
feature == RENDERFEATURE_PIXEL_RATIO ||
feature == RENDERFEATURE_ROTATION ||
feature == RENDERFEATURE_POSTPROCESS ||
feature == RENDERFEATURE_TONEMAP)
return true;
return false;
}
bool CWinRenderer::Supports(ESCALINGMETHOD method)
{
if (!m_bConfigured)
return false;
return m_renderer->Supports(method);
}
bool CWinRenderer::WantsDoublePass()
{
if (!m_bConfigured)
return false;
return m_renderer->WantsDoublePass();
}
bool CWinRenderer::ConfigChanged(const VideoPicture& picture)
{
if (!m_bConfigured)
return true;
return picture.videoBuffer->GetFormat() != m_format;
}
CRenderInfo CWinRenderer::GetRenderInfo()
{
if (!m_bConfigured)
return {};
return m_renderer->GetRenderInfo();
}
void CWinRenderer::ReleaseBuffer(int idx)
{
if (!m_bConfigured)
return;
m_renderer->ReleaseBuffer(idx);
}
bool CWinRenderer::NeedBuffer(int idx)
{
if (!m_bConfigured)
return false;
return m_renderer->NeedBuffer(idx);
}
ยดยดยด
Change
nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU, displayIdArray, &displayIdCount, flags);
to
nvStatus = NvAPI_GPU_GetConnectedDisplayIds(ahGPU[i], displayIdArray, &displayIdCount, flags);
Thanks to #1201ProgramAlarm

Error in Xcode: Thread 1: EXC_BAD_ACCESS (code=1, address=0xe8)

This is supposed to be a c++ game which works by reading in files. How ever, I am not really sure what is the problem in the code below. When I enter the file name it gives me this error (code is below, problematic line is also shown). If you can't fix it can you at least tell me why this seems to work fine in another computer, but when I try to compile in Xcode it goes wrong?
#include "AdvRoom.h"
AdvRoom::AdvRoom()
{
}
bool AdvRoom::readRoom(ifstream &roomFile)
{
bool success = true;
char data[64];
int pointer;
while ((roomFile.get(data[0])) && data[0] == '\n') {}
roomFile.unget();
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
this->number = atoi(data);
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
this->name = data;
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
while (data[0] != '-' && success) {
this->description.push_back(data);
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data[0]);
roomFile.get(data, 64);
}
else success = false;
}
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
// Check for \n
string direction;
int destination = 0;
string key;
while (roomFile.peek() != '\n' && success) {
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64, ' ');
direction = data;
while ((roomFile.get(data[0])) && data[0] == ' ') {}
roomFile.unget();
int i = 0;
while ((roomFile.get(data[i])) && data[i] != '\n' && data[i] != ' ') {
++i;
}
if (data[i] == ' ') {
data[i] = '\0';
destination = atoi(data);
roomFile.get(data, 64, '\n');
key = data;
roomFile.get(data[0]);
}
else if (data[i] == '\n') {
data[i] = '\0';
destination = atoi(data);
key = "";
//roomFile.get(data[0]);
}
AdvMotionTableEntry entry(direction, destination, key);
this->motionTable.push_back(entry);
}
else success = false;
}
}
else success = false;
return success;
}
vector<string> AdvRoom::getDescription()
{
vector<string> copyDesc = this->description;
return copyDesc;
}
string AdvRoom::getName()
{
string copyName = this->name;
return copyName;
}
void AdvRoom::addObject(AdvObject obj)
{
// This function should add the obj to the room.
// It however, should not add the object to the room
// if the room already contains the object.
this->objects.push_back(obj);
}
AdvObject AdvRoom::removeObject(string objName)
{
AdvObject deletedObj;
// This function should remove the object with objName.
for (int i = 0; i < this->objects.size(); ++i) {
if (this->objects[i].getName() == objName) {
deletedObj = this->objects[i];
this->objects.erase(this->objects.begin() + i);
}
}
return deletedObj;
}
bool AdvRoom::containsObject(string objName)
{
// Returns true if object with objName is in the room.
bool success = false;
for (int i = 0; i < this->objects.size(); ++i) {
if (this->objects[i].getName() == objName) {
success = true;
}
}
return success;
}
int AdvRoom::objectCount()
{
return this->objects.size();
}
AdvObject AdvRoom::getObject(int index)
{
return this->objects.at(index);
}
bool AdvRoom::hasBeenVisited()
{
bool truth = this->isVisited;
return truth;
}
void AdvRoom::setVisited(bool flag)
{
this->isVisited = flag;
}
vector<AdvMotionTableEntry> AdvRoom::getMotionTable()
{
vector<AdvMotionTableEntry> copyMotionTable = this->motionTable;
return copyMotionTable;
}
int AdvRoom::getRoomNumber()
{
int copyNumber = this->number;
return copyNumber;
}

error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::pair<const _Kty,_Ty>'

I have this error in my code, here is the code:
`
#pragma once
#include <WinSock2.h>
#include <Windows.h>
#include "TriviaServer.h"
#include "Validator.h"
#define PORT 8820
#define IFACE 0
#include <algorithm>
using namespace std;
TriviaServer::TriviaServer()
{
_roomIdSequence = 0;
_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_socket == INVALID_SOCKET)
throw std::exception(__FUNCTION__ " - socket");
/*DataBase Build*/
}
TriviaServer::~TriviaServer()
{
map<int, Room*>::iterator it = _roomsList.begin();
for (it; it != _roomsList.end(); it++)
{
delete it->second;
}
map<SOCKET, User*>::iterator it2 = _connectedUsers.begin();
for (it2; it2 != _connectedUsers.end(); it2++)
{
delete it2->second;
closesocket(it2->first);
}
closesocket(_socket);
}
void TriviaServer::server()
{
bindAndListen();
thread handleMessages(&TriviaServer::handleRecievedMessages);
handleMessages.detach();
while (true)
{
cout << "accepting client..." << endl;
accept();
}
}
void TriviaServer::bindAndListen()
{
struct sockaddr_in sa = { 0 };
sa.sin_port = htons(PORT);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = IFACE;
if (::bind(_socket, (struct sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR)
throw std::exception(__FUNCTION__ " - bind");
cout << "binded" << endl;
if (::listen(_socket, SOMAXCONN) == SOCKET_ERROR)
throw std::exception(__FUNCTION__ " - listen");
cout << "listening..." << endl;
}
void TriviaServer::accept()
{
SOCKET client_socket = ::accept(_socket, NULL, NULL);
if (client_socket == INVALID_SOCKET)
throw std::exception(__FUNCTION__);
cout << "Client accepted !" << endl;
// create new thread for client and detach from it
std::thread tr(&TriviaServer::clientHandler, this, client_socket);
tr.detach();
}
void TriviaServer::clientHandler(SOCKET s)
{
bool clientConnected = true;
while (clientConnected)
{
int code = Helper::getMessageTypeCode(s);
RecievedMessage* m = buildRecieveMessage(s, code);
addRecievedMessage(m);
}
}
void TriviaServer::safeDeleteUser(RecievedMessage* m)
{
try
{
SOCKET soc = m->getSock();
handleSignout(m);
if (soc != NULL)
{
closesocket(soc);
}
}
catch (...)
{ }
}
void TriviaServer::addRecievedMessage(RecievedMessage* m)
{
std::unique_lock<std::mutex> locker(_mtxRecievedMessages);
m->setUser(getUserBySocket(m->getSock()));
locker.lock();
_queRcvMessages.push(m);
locker.unlock();
_cond.notify_one();
}
RecievedMessage* TriviaServer::buildRecieveMessage(SOCKET s, int code)
{
vector<string> values;
int len;
switch (code)
{
case SIGN_IN_REQUEST:
for (int i = 0; i < 2; i++)
{
len = Helper::getIntPartFromSocket(s, 2);
values.push_back(Helper::getStringPartFromSocket(s, len));
}
break;
case SIGN_OUT_REQUEST:
break;
case SIGN_UP_REQUEST:
for (int i = 0; i < 3; i++)
{
len = Helper::getIntPartFromSocket(s, 2);
values.push_back(Helper::getStringPartFromSocket(s, len));
}
break;
case AVAILABLE_ROOM_REQUEST:
break;
case ROOM_USERS_REQUEST:
case ROOM_JOIN_REQUEST:
values.push_back(Helper::getStringPartFromSocket(s, 4));
break;
case ROOM_LEAVE_REQUEST:
break;
case ROOM_CREATE_REQUEST:
len = Helper::getIntPartFromSocket(s, 2);
values.push_back(Helper::getStringPartFromSocket(s, len));
values.push_back(Helper::getStringPartFromSocket(s, 1));
values.push_back(Helper::getStringPartFromSocket(s, 2));
values.push_back(Helper::getStringPartFromSocket(s, 2));
break;
case ROOM_CLOSE_REQUEST:
break;
case EXIT_APPLICATION:
break;
}
RecievedMessage* m;
if (!values.empty())
{
m = new RecievedMessage(s, code, values);
}
else
{
m = new RecievedMessage(s, code);
}
return m;
}
void TriviaServer::handleRecievedMessages()
{
std::unique_lock<std::mutex> locker(_mtxRecievedMessages);
while (true)
{
if (_queRcvMessages.empty())
{
_cond.wait(locker);
}
switch (_queRcvMessages.front()->getMessageCode())
{
case SIGN_IN_REQUEST:
handleSignin(_queRcvMessages.front());
break;
case SIGN_OUT_REQUEST:
handleSignout(_queRcvMessages.front());
break;
case SIGN_UP_REQUEST:
handleSignup(_queRcvMessages.front());
break;
case AVAILABLE_ROOM_REQUEST:
handleGetRooms(_queRcvMessages.front());
break;
case ROOM_USERS_REQUEST:
handleGetUsersInRoom(_queRcvMessages.front());
break;
case ROOM_JOIN_REQUEST:
handleJoinRoom(_queRcvMessages.front());
break;
case ROOM_LEAVE_REQUEST:
handleLeaveRoom(_queRcvMessages.front());
break;
case ROOM_CREATE_REQUEST:
handleCreateRoom(_queRcvMessages.front());
break;
case ROOM_CLOSE_REQUEST:
handleCloseRoom(_queRcvMessages.front());
break;
case EXIT_APPLICATION:
handleSignout(_queRcvMessages.front());
break;
}
_queRcvMessages.pop();
}
}
User* TriviaServer::getUserBySocket(SOCKET s)
{
std::map<SOCKET, User*>::iterator it;
it = find(_connectedUsers.begin(), _connectedUsers.end(), s);
if (it != _connectedUsers.end())
{
return it->second;
}
else
{
return NULL;
}
}
User* TriviaServer::handleSignin(RecievedMessage* m)
{
int flag = true; // if wrong details
map<string, string>::iterator it;
map<SOCKET,User*>::iterator itConnected;
User* login = nullptr;
for (it = _dbUsers.begin(); it != _dbUsers.end(); it++)
{
if ((it->first) == ((*(m->getValues()))[0]) && (it->second) == ((*(m->getValues()))[1]))
{
flag = false;
login = new User(it->first, m->getSock());
for (itConnected = _connectedUsers.begin(); itConnected != _connectedUsers.end(); it++)
{
if (itConnected->second->getUsername() == login->getUsername())
{
delete login;
login = nullptr;
}
}
}
}
if (login)
{
Helper::sendData(m->getSock(), to_string(SIGN_IN_SUCCESS));
}
else if (flag)
{
Helper::sendData(m->getSock(), to_string(SIGN_IN_WRONG_DETAILS));
}
else
{
Helper::sendData(m->getSock(), to_string(SIGN_IN_USER_CONNECTED));
}
return login;
}
bool TriviaServer::handleSignup(RecievedMessage* m)
{
//[203##username##pass##email]
string user = (*m->getValues())[0];
string pass = (*m->getValues())[1];
string email = (*m->getValues())[2];
if (!Validator::isPasswordValid(pass))
{
Helper::sendData(m->getSock(), to_string(SIGN_UP_PASS_ILLEGAL));
return false;
}
if (!Validator::isUsernameValid(user))
{
Helper::sendData(m->getSock(), to_string(SIGN_UP_USERNAME_ILLEGAL));
return false;
}
//////////////////// TEMP CODE
map<string, string>::iterator it = _dbUsers.begin();
for (it; it != _dbUsers.end(); it++)
{
if (user == it->first)
{
Helper::sendData(m->getSock(), to_string(SIGN_UP_USERNAME_EXISTS));
return false;
}
}
_dbUsers.insert(pair<string, string>(user, pass));
//////////////////// END TEMP CODE
//////////////////// FUTURE CODE:
/*if (!DataBase::isUserExists(user))
{
Helper::sendData(m->getSock(), to_string(SIGN_UP_USERNAME_EXISTS));
return false;
}
if(!DataBase::addNewUser(user, pass, email))
{
Helper::sendData(m->getSock(), to_string(SIGN_UP_OTHER));
return false;
}
*/
Helper::sendData(m->getSock(), to_string(SIGN_UP_SUCCESS));
return true;
}
void TriviaServer::handleSignout(RecievedMessage* m)
{
User* u;
if (u = m->getUser())
{
map<SOCKET, User*>::iterator it = _connectedUsers.begin();
for (it; it != _connectedUsers.end(); it++)
{
if (it->first == u->getSocket())
{
delete it->second;
closesocket(it->first);
}
}
handleCloseRoom(m);
handleLeaveRoom(m);
//handleLeaveGame(m);
}
}
bool TriviaServer::handleCreateRoom(RecievedMessage* m)
{
User* curr = m->getUser();
if (curr)
{
vector<string>* values = m->getValues();
if (curr->createRoom(++_roomIdSequence, m->getUser(),(*values)[0] ,stoi((*values)[1], nullptr, 0), stoi((*values)[3], nullptr, 0), stoi((*values)[2], nullptr, 0)))
{
_roomsList.insert(pair<int, Room*>(_roomIdSequence, curr->getRoom()));
return true;
}
return false;
}
else
{
return false;
}
}
bool TriviaServer::handleCloseRoom(RecievedMessage* m)
{
}
bool TriviaServer::handleJoinRoom(RecievedMessage* m)
{
}
bool TriviaServer::handleLeaveRoom(RecievedMessage* m)
{
}
void TriviaServer::handleGetUsersInRoom(RecievedMessage* m)
{
}
void TriviaServer::handleGetRooms(RecievedMessage* m)
{
}
`
I tried to put comments on all the '==' and '!=' to search where is the problem but the error keep showing up.
it is in this cpp file, as far as i can tell from the code (the only file i can't compile)
thanks for the help,
sorry for the long code,
Omer
The problem was the order of the includes in other headers that included,
it should be
#include <WinSock2.h>
#include <Windows.h>
and not the other way around!

Mix_LoadWAV returns NULL when it shouldn't

I'm making a game in C++, but I've been running into an issue I just can't figure out when it comes to the sound. I'm using SDL_Mixer, with Mix_Music for the music and Mix_Chunk for the sound effects, but for some reason when I try to load a sound effect file using MIX_LoadWAV it returns NULL.
The thing is, when I load the same file using MIX_LoadMUS (loading as music instead of sound effect), it loads fine.
I can't find any differences that would explain the issue; the only difference is Mix_LoadWAV instead of Mix_LoadMUS, but why? Mix_LoadMUS doesn't work for Mix_Chunk, or else I'd just use that, but ...
Here, I'll show you the code for the sound manager I use. MusicClip being a Mix_Music and SoundClip being a Mix_Chunk.
#include "stdafx.h"
#include "SoundManager.h"
#include "MusicClip.h"
#include "SoundClip.h"
SoundManager::SoundManager()
{
}
SoundManager::~SoundManager()
{
Shutdown();
}
bool SoundManager::Initialize()
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
printf(" SDL_mixer :: Msx_OpenAudio %s\n", Mix_GetError());
return false;
}
return true;
}
void SoundManager::Shutdown()
{
for (unsigned int i = 0; i < m_axSoundClips.size(); i++)
{
delete m_axSoundClips[i];
m_axSoundClips[i] = nullptr;
}
m_axSoundClips.clear();
for (unsigned int i = 0; i < m_axMusicClips.size(); i++)
{
delete m_axMusicClips[i];
m_axMusicClips[i] = nullptr;
}
m_axMusicClips.clear();
{
std::map<std::string, Mix_Chunk*>::iterator it = m_axSounds.begin();
while (it != m_axSounds.end())
{
Mix_FreeChunk(it->second);
it->second = nullptr;
it++;
}
m_axSounds.clear();
}
{
std::map<std::string, Mix_Music*>::iterator it = m_axMusic.begin();
while (it != m_axMusic.end())
{
Mix_FreeMusic(it->second);
it->second = nullptr;
it++;
}
m_axMusic.clear();
}
Mix_CloseAudio();
}
MusicClip *SoundManager::CreateMusicClip(std::string p_sFilename)
{
MusicClip *Ret = nullptr;
std::map<std::string, Mix_Music*>::iterator it = m_axMusic.find(p_sFilename);
if (it == m_axMusic.end())
{
Mix_Music* Music = Mix_LoadMUS(p_sFilename.c_str());
if (Music == NULL) {
printf("Error; music will not play\n");
printf(p_sFilename.c_str());
printf("\n");
printf(Mix_GetError());
}
std::pair<std::string, Mix_Music*> Pair;
Pair = std::make_pair(p_sFilename, Music);
Ret = new MusicClip(Music);
}
else
Ret = new MusicClip(it->second);
m_axMusicClips.push_back(Ret);
return Ret;
}
SoundClip *SoundManager::CreateSoundClip(std::string p_sFilename)
{
SoundClip *Ret = nullptr;
std::map<std::string, Mix_Chunk*>::iterator it = m_axSounds.find(p_sFilename);
if (it == m_axSounds.end())
{
Mix_Chunk* Sound = Mix_LoadWAV(p_sFilename.c_str());
if (Sound == NULL) {
printf("\nError; sound will not play\n");
printf(p_sFilename.c_str());
printf("\n");
printf(Mix_GetError());
}
std::pair<std::string, Mix_Chunk*> Pair;
Pair = std::make_pair(p_sFilename, Sound);
Ret = new SoundClip(Sound);
}
else
Ret = new SoundClip(it->second);
m_axSoundClips.push_back(Ret);
return Ret;
}
Here's the code for MusicClip and SoundClip; They seem identical aside from me adding PlayOnce and fadeout to MusicClip.
#include "stdafx.h"
#include "SoundClip.h"
SoundClip::SoundClip()
{
m_pxClip = nullptr;
m_iChannel = -1;
}
SoundClip::~SoundClip()
{
m_pxClip = nullptr;
}
SoundClip::SoundClip(Mix_Chunk* p_pxClip)
{
m_pxClip = p_pxClip;
m_iChannel = -1;
}
void SoundClip::Play()
{
m_iChannel = Mix_PlayChannel(-1, m_pxClip, 0);
}
void SoundClip::Stop()
{
if (m_iChannel == -1)
return;
Mix_HaltChannel(m_iChannel);
m_iChannel = -1;
}
void SoundClip::Volume(int p_iVolume)
{
if (m_iChannel == -1)
return;
Mix_Volume(m_iChannel, p_iVolume);
}
void SoundClip::Pause()
{
if (m_iChannel == -1)
return;
if (Mix_Paused(m_iChannel))
{
Mix_Resume(m_iChannel);
}
else
{
Mix_Pause(m_iChannel);
}
}
-
// MusicClip.cpp
#include "stdafx.h"
#include "MusicClip.h"
MusicClip::MusicClip()
{
m_xClip = nullptr;
m_iChannel = -1;
}
MusicClip::~MusicClip()
{
m_xClip = nullptr;
m_iChannel = -1;
}
MusicClip::MusicClip(Mix_Music* p_xClip)
{
m_xClip = p_xClip;
m_iChannel = -1;
}
void MusicClip::Play()
{
m_iChannel = Mix_PlayMusic(m_xClip, -1);
}
void MusicClip::PlayOnce()
{
m_iChannel = Mix_PlayMusic(m_xClip, 1);
}
void MusicClip::Pause()
{
if (m_iChannel == -1)
return;
if ( Mix_PausedMusic() )
Mix_ResumeMusic();
else
Mix_Pause(m_iChannel);
}
void MusicClip::Volume(int p_iVolume)
{
Mix_VolumeMusic(p_iVolume);
oldVolume = p_iVolume;
}
void MusicClip::FadeOut()
{
if (oldVolume>0)
oldVolume--;
Mix_VolumeMusic(oldVolume);
}
void MusicClip::Stop()
{
if (m_iChannel == -1)
return;
Mix_HaltChannel(m_iChannel);
m_iChannel = -1;
}
And this is the code I use to call on the functions. (The soundManager was initialized earlier in the program to start up the BGM.) So this, using the Mix_Chunk* SFX2, won't work:
void GameState::playSFX(std::string FX)
{
SFX2 = soundManager.CreateSoundClip("../assets/sfx/sfx-bleep.wav");
SFX2->Volume(60);
SFX2->Play();
}
But for some reason, if I change SFX2 to a Mix_Music*, this DOES work.
void GameState::playSFX(std::string FX)
{
SFX2 = soundManager.CreateMusicClip("../assets/sfx/sfx-bleep.wav");
SFX2->Volume(60);
SFX2->Play();
}
What do I do? Mix_GetError() doesn't return anything either... If I write the path wrong it returns "couldn't open file", so clearly it can find/open the file, it just... won't? I can't just use Mix_Music for my sound effects either, because if I do they cancel out the music.
By the way, I don't know if it's related, but Mix_LoadMUS won't load non-wav files even though it's supposed to support .ogg and .mp3 too?