Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
# Microsoft Developer Studio Project File - Name="MedParamBase" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=MedParamBase - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "MedParamBase.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "MedParamBase.mak" CFG="MedParamBase - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MedParamBase - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "MedParamBase - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "MedParamBase - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MedParamBase - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "MedParamBase - Win32 Release"
# Name "MedParamBase - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\alist.cpp
# End Source File
# Begin Source File
SOURCE=.\param.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\alist.h
# End Source File
# Begin Source File
SOURCE=.\param.h
# End Source File
# Begin Source File
SOURCE=.\validate.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,119 @@
//------------------------------------------------------------------------------
// File: AList.cpp
//
// Desc: DirectShow sample code - implementation of AListItem and AList
// classes.
//
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <windows.h>
#include "alist.h"
LONG AListItem::GetCount(void) const
{
LONG l;
const AListItem *li;
for(l=0,li=this; li!=NULL ; li=li->m_pNext,++l);
return l;
}
AListItem* AListItem::Cat(AListItem *pItem)
{
AListItem *li;
if(this==NULL)
return pItem;
for(li=this ; li->m_pNext!=NULL ; li=li->m_pNext);
li->m_pNext=pItem;
return this;
}
//////////////////////////////////////////////////////////////////////
// AListItem::Remove
AListItem* AListItem::Remove(AListItem *pItem)
{
AListItem *li,*prev;
//treat remove(NULL) same as item not found in list
if (pItem==NULL)
return this;
if(pItem==this)
return m_pNext;
prev=NULL;
for(li=this; li!=NULL && li!=pItem ; li=li->m_pNext)
prev=li;
if(li==NULL) // item not found in list
return this;
// here it is guaranteed that prev is non-NULL since we checked for
// that condition at the very beginning
prev->SetNext(li->m_pNext);
li->SetNext(NULL);
// SetNext on pItem to NULL
pItem->SetNext(NULL);
return this;
}
AListItem* AListItem::GetPrev(AListItem *pItem) const
{
const AListItem *li,*prev;
prev=NULL;
for(li=this ; li!=NULL && li!=pItem ; li=li->m_pNext)
prev=li;
return (AListItem*)prev;
}
AListItem * AListItem::GetItem(LONG index)
{
AListItem *scan;
for (scan = this; scan!=NULL && index; scan = scan->m_pNext)
{
index--;
}
return (scan);
}
void AList::InsertBefore(AListItem *pItem,AListItem *pInsert)
{
AListItem *prev = GetPrev(pItem);
pInsert->SetNext(pItem);
if (prev) prev->SetNext(pInsert);
else m_pHead = pInsert;
}
void AList::AddTail(AListItem *pItem)
{
if (m_pHead == NULL)
{
AddHead(pItem);
}
else
{
m_pHead = m_pHead->AddTail(pItem);
}
}
void AList::Reverse()
{
AList Temp;
AListItem *pItem;
while ((pItem = RemoveHead()) != 0)
{
Temp.AddHead(pItem);
}
Cat(Temp.GetHead());
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// File: AList.h
//
// Desc: DirectShow sample code - definitions of AListItem and AList classes.
//
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __ALIST_H__
#define __ALIST_H__
class AListItem
{
public:
AListItem() { m_pNext=NULL; };
AListItem *GetNext() const {return m_pNext;};
void SetNext(AListItem *pNext) {m_pNext=pNext;};
LONG GetCount() const;
AListItem* Cat(AListItem* pItem);
AListItem* AddTail(AListItem* pItem) {return Cat(pItem);};
AListItem* Remove(AListItem* pItem);
AListItem* GetPrev(AListItem *pItem) const;
AListItem* GetItem(LONG index);
private:
AListItem *m_pNext;
};
class AList
{
public:
AList() {m_pHead=NULL;};
AListItem *GetHead() const { return m_pHead;};
void RemoveAll() { m_pHead=NULL;};
LONG GetCount() const {return m_pHead->GetCount();};
AListItem *GetItem(LONG index) { return m_pHead->GetItem(index);};
void InsertBefore(AListItem *pItem,AListItem *pInsert);
void Cat(AListItem *pItem) {m_pHead=m_pHead->Cat(pItem);};
void Cat(AList *pList)
{
// assert(pList!=NULL);
m_pHead=m_pHead->Cat(pList->GetHead());
};
void AddHead(AListItem *pItem)
{
// assert(pItem!=NULL);
pItem->SetNext(m_pHead);
m_pHead=pItem;
}
void AddTail(AListItem *pItem);// {m_pHead=m_pHead->AddTail(pItem);};
void Remove(AListItem *pItem) {m_pHead=m_pHead->Remove(pItem);};
AListItem *GetPrev(AListItem *pItem) const {return m_pHead->GetPrev(pItem);};
AListItem *GetTail() const {return GetPrev(NULL);};
BOOL IsEmpty(void) const {return (m_pHead==NULL);};
AListItem *RemoveHead(void)
{
AListItem *li;
li=m_pHead;
if(m_pHead)
m_pHead=m_pHead->GetNext();
// li->SetNext(NULL);
return li;
}
void Reverse();
protected:
AListItem *m_pHead;
};
#endif // __ALIST_H__

View File

@@ -0,0 +1,575 @@
//------------------------------------------------------------------------------
// File: Param.cpp
//
// Desc: DirectShow sample code - definition of CParamsManager class.
//
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <windows.h>
#include <medparam.h>
#include "alist.h"
#include "param.h"
#include "dmerror.h"
#include "param.h"
#include "math.h"
#include "validate.h"
// Disable some /W4 level warnings
#pragma warning(disable:4296 4100 4505)
CCurveList::~CCurveList()
{
while(this->GetHead())
{
delete this->RemoveHead();
}
}
CParamsManager::CParamsManager()
{
m_fDirty = FALSE;
m_cTimeFormats = 0;
m_pguidTimeFormats = NULL;
m_guidCurrentTimeFormat = GUID_NULL;
m_cParams = 0;
m_pCurveLists = NULL;
m_pParamInfos = NULL;
m_dwActiveBits = 0;
InitializeCriticalSection(&m_ParamsCriticalSection);
}
CParamsManager::~CParamsManager()
{
delete[] m_pguidTimeFormats;
delete[] m_pCurveLists;
delete[] m_pParamInfos;
DeleteCriticalSection(&m_ParamsCriticalSection);
}
HRESULT CParamsManager::InitParams(DWORD cTimeFormats, const GUID *pguidTimeFormats, DWORD dwFormatIndex, MP_TIMEDATA mptdTimeData, DWORD cParams, ParamInfo *pParamInfo)
{
//check that the index is in a valid range
if (0 > dwFormatIndex || dwFormatIndex >= cTimeFormats || cParams > sizeof(DWORD) * 8)
return E_INVALIDARG;
m_pCurveLists = new CCurveList[cParams];
if (!m_pCurveLists)
return E_OUTOFMEMORY;
// save the time formats
m_pguidTimeFormats = new GUID[cTimeFormats];
if (!m_pguidTimeFormats)
return E_OUTOFMEMORY;
for (DWORD dwIndex = 0; dwIndex < cTimeFormats; dwIndex++)
{
memcpy(&m_pguidTimeFormats[dwIndex], &pguidTimeFormats[dwIndex], sizeof(*pguidTimeFormats));
}
// save the count of formats
m_cTimeFormats = cTimeFormats;
// save the current time format
m_guidCurrentTimeFormat = m_pguidTimeFormats[dwFormatIndex];
// save the TimeData
m_mptdCurrentTimeData = mptdTimeData;
// save the parameter info
m_pParamInfos
= new ParamInfo[cParams];
if (!m_pParamInfos)
return E_OUTOFMEMORY;
for (dwIndex = 0; dwIndex < cParams; dwIndex++)
{
if (pParamInfo[dwIndex].dwIndex < cParams)
{
memcpy(&m_pParamInfos[pParamInfo[dwIndex].dwIndex],&pParamInfo[dwIndex],sizeof(ParamInfo));
}
}
m_cParams = cParams;
return S_OK;
}
HRESULT CParamsManager::GetParamCount(DWORD *pdwParams)
{
if (pdwParams == NULL)
return E_POINTER;
*pdwParams = m_cParams;
return S_OK;
}
HRESULT CParamsManager::GetParamInfo(DWORD dwParamIndex,MP_PARAMINFO *pInfo)
{
if (!pInfo)
{
return E_POINTER;
}
if (dwParamIndex < m_cParams)
{
*pInfo = m_pParamInfos[dwParamIndex].MParamInfo;
return S_OK;
}
else
{
return E_INVALIDARG;
}
}
HRESULT CParamsManager::GetParamText(DWORD dwParamIndex,WCHAR **ppwchText)
{
if (!ppwchText)
{
return E_POINTER;
}
if (dwParamIndex < m_cParams)
{
// write string of format: "Label\0Unit\0Enums1\0Enum2\0...EnumN\0\0"
ParamInfo &pinfo = m_pParamInfos[dwParamIndex];
int iUnit = wcslen(pinfo.MParamInfo.szLabel) + 1; // begin writing unit text here
int iEnums = iUnit + wcslen(pinfo.MParamInfo.szUnitText) + 1; // begin writing enum text here
int iEnd = iEnums + wcslen(pinfo.pwchText) + 1; // write the final (second) null terminator here
WCHAR *pwsz = static_cast<WCHAR *>(CoTaskMemAlloc((iEnd + 1) * sizeof(WCHAR)));
if (!pwsz)
return E_OUTOFMEMORY;
// wcscpy will write into various points of the string, neatly terminating each with a null
wcscpy(pwsz, pinfo.MParamInfo.szLabel);
wcscpy(pwsz + iUnit, pinfo.MParamInfo.szUnitText);
wcscpy(pwsz + iEnums, pinfo.pwchText);
// The text field was defined with commas to separate the enum values.
// Replace them with NULL characters now.
for (WCHAR *pwch = pwsz + iEnums; *pwch; ++pwch)
{
if (*pwch == L',')
*pwch = L'\0';
}
pwsz[iEnd] = L'\0';
*ppwchText = pwsz;
return S_OK;
}
else
{
return E_INVALIDARG;
}
}
HRESULT CParamsManager::GetNumTimeFormats(DWORD *pdwNumTimeFormats)
{
if (!pdwNumTimeFormats)
{
return E_POINTER;
}
*pdwNumTimeFormats = m_cTimeFormats;
return S_OK;
}
HRESULT CParamsManager::GetSupportedTimeFormat(DWORD dwFormatIndex,GUID *pguidTimeFormat)
{
if (!pguidTimeFormat)
{
return E_POINTER;
}
if (dwFormatIndex >= m_cTimeFormats)
{
return E_INVALIDARG;
}
*pguidTimeFormat = m_pguidTimeFormats[dwFormatIndex];
return S_OK;
}
HRESULT CParamsManager::GetCurrentTimeFormat( GUID *pguidTimeFormat,MP_TIMEDATA *pTimeData)
{
HRESULT hr=S_OK;
// Parameter Validation
if ((pguidTimeFormat == NULL) || (pTimeData == NULL))
{
hr = E_POINTER;
}
// Return the values
if (SUCCEEDED(hr))
{
*pguidTimeFormat = m_guidCurrentTimeFormat;
*pTimeData = m_mptdCurrentTimeData;
}
return hr;
}
HRESULT CParamsManager::CopyParamsFromSource( CParamsManager * pSource)
{
HRESULT hr = S_OK;
DWORD dwIndex;
for (dwIndex = 0; dwIndex < m_cTimeFormats; dwIndex++)
{
if (pSource->m_guidCurrentTimeFormat == m_pguidTimeFormats[dwIndex])
{
break;
}
}
hr = InitParams(pSource->m_cTimeFormats, pSource->m_pguidTimeFormats, dwIndex, pSource->m_mptdCurrentTimeData, pSource->m_cParams,pSource->m_pParamInfos);
if (SUCCEEDED(hr))
{
for (dwIndex = 0; dwIndex < m_cParams; dwIndex++)
{
CCurveItem *pCurve = pSource->m_pCurveLists[dwIndex].GetHead();
for (;pCurve;pCurve = pCurve->GetNext())
{
CCurveItem *pNew = new CCurveItem;
if (!pNew)
{
return E_OUTOFMEMORY;
}
pNew->m_Envelope = pCurve->m_Envelope;
m_pCurveLists[dwIndex].AddTail(pNew);
}
}
}
return hr;
}
void
CParamsManager ::UpdateActiveParams(REFERENCE_TIME rtTime, UpdateCallback &rThis)
{
if (!m_dwActiveBits)
return; // nothing to recalc
DWORD dwBit = 1;
for (DWORD dwIndex = 0; dwIndex < m_cParams; dwIndex++, dwBit = dwBit << 1)
{
if (m_dwActiveBits & dwBit)
{
float fVal = 0;
HRESULT hr = GetParamFloat(dwIndex, rtTime, &fVal);
rThis.SetParamUpdate(dwIndex, fVal);
if (hr == S_FALSE)
m_dwActiveBits &= ~dwBit; // we're beyond the last curve, don't need to recalc next time
//TraceI(6, "DMO value: time %I64d, param #%d, current value %hf\n", rtTime, dwIndex, fVal);
}
}
}
inline float ValRange(float valToClip, float valMin, float valMax)
{
return valToClip < valMin
? valMin
: (valToClip > valMax ? valMax : valToClip);
}
HRESULT CParamsManager::GetParamFloat(DWORD dwParamIndex,REFERENCE_TIME rtTime,float *pval)
{
HRESULT hr = S_OK;
if (dwParamIndex >= m_cParams)
return E_INVALIDARG;
EnterCriticalSection(&m_ParamsCriticalSection);
CCurveList *pList = &m_pCurveLists[dwParamIndex];
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
// if no points, then neutral value
CCurveItem *pCurveHead = pList->GetHead();
if (!pCurveHead)
{
*pval = pInfo->MParamInfo.mpdNeutralValue;
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_FALSE;
}
// Find the curve during or before the requested time
// If the time is during a curve, we will use that.
// If not, we need the end value of the previous curve.
// Our list keeps these in backwards order, so we are scanning from the
// highest point in time backwards.
for (CCurveItem *pCurve = pCurveHead; pCurve && pCurve->m_Envelope.rtStart > rtTime;pCurve = pCurve->GetNext());
// If there is no pCurve, there was no curve prior to or during rtTime. Give up.
if (!pCurve)
{
*pval = pInfo->MParamInfo.mpdNeutralValue;
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_OK;
}
// Now, if pCurve ends before the requested time,
// return the final value of pCurve, since that will hold until the start of the next curve.
if (pCurve->m_Envelope.rtEnd < rtTime)
{
*pval = pCurve->m_Envelope.valEnd;
LeaveCriticalSection(&m_ParamsCriticalSection);
if (pCurve == pCurveHead)
return S_FALSE; // past last curve
else
return S_OK; // there are more curves ahead
}
// If we get this far, the curve must bound rtTime.
if (pCurve->m_Envelope.iCurve & MP_CURVE_JUMP)
{
*pval = pCurve->m_Envelope.valEnd;
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_OK;
}
REFERENCE_TIME rtTimeChange = pCurve->m_Envelope.rtEnd - pCurve->m_Envelope.rtStart;
REFERENCE_TIME rtTimeIntermediate = rtTime - pCurve->m_Envelope.rtStart;
float fltScalingX = static_cast<float>(rtTimeIntermediate) / rtTimeChange; // horizontal distance along curve between 0 and 1
float fltScalingY; // height of curve at that point between 0 and 1 based on curve function
switch (pCurve->m_Envelope.iCurve)
{
case MP_CURVE_SQUARE:
fltScalingY = fltScalingX * fltScalingX;
break;
case MP_CURVE_INVSQUARE:
fltScalingY = (float) sqrt(fltScalingX);
break;
case MP_CURVE_SINE:
// <20><> Maybe we should have a lookup table here?
fltScalingY = (float) (sin(fltScalingX * 3.1415926535 - (3.1415926535/2)) + 1) / 2;
break;
case MP_CURVE_LINEAR:
default:
fltScalingY = fltScalingX;
}
// Find out if we need to pull the start point from the previous curve,
// the default neutral value, or the current curve.
float fStartVal = pCurve->m_Envelope.valStart;
if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_NEUTRALVAL)
{
fStartVal = pInfo->MParamInfo.mpdNeutralValue;
}
// Currentval, if it exists, will override neutralval.
if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_CURRENTVAL)
{
// Take advantage of the fact that these are inserted in backwards order.
// Scan for the previous curve that ends before this time.
CCurveItem *pPrevious = pCurve->GetNext();
for (;pPrevious && pPrevious->m_Envelope.rtEnd > rtTime;pPrevious = pPrevious->GetNext());
if (pPrevious)
{
fStartVal = pPrevious->m_Envelope.valEnd;
}
}
// Apply that scaling to the range of the actual points
*pval = (pCurve->m_Envelope.valEnd - fStartVal) * fltScalingY + fStartVal;
LeaveCriticalSection(&m_ParamsCriticalSection);
return hr;
}
HRESULT CParamsManager::GetParamInt(DWORD dwParamIndex,REFERENCE_TIME rt,long *pval)
{
HRESULT hr = E_POINTER;
if (pval)
{
float fVal;
hr = GetParamFloat(dwParamIndex,rt,&fVal);
if (SUCCEEDED(hr))
{
*pval = (long) (fVal + 1/2); // Round.
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////
// IMediaParams
HRESULT CParamsManager::GetParam(DWORD dwParamIndex,MP_DATA *pValue)
{
V_INAME(CParams::GetParam);
V_PTR_WRITE(pValue, MP_DATA);
if (dwParamIndex >= m_cParams)
return E_INVALIDARG;
EnterCriticalSection(&m_ParamsCriticalSection);
CCurveList *pList = &m_pCurveLists[dwParamIndex];
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
// if no points, then neutral value
CCurveItem *pCurve = pList->GetHead();
if (pCurve)
{
*pValue = pCurve->m_Envelope.valEnd;
}
else
{
*pValue = pInfo->MParamInfo.mpdNeutralValue;
}
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_OK;
}
HRESULT CParamsManager::SetParam(DWORD dwParamIndex,MP_DATA value)
{
V_INAME(CParams::SetParam);
if (dwParamIndex >= m_cParams)
return E_INVALIDARG;
EnterCriticalSection(&m_ParamsCriticalSection);
m_fDirty = TRUE;
CCurveList *pList = &m_pCurveLists[dwParamIndex];
// ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
// If we've already got a list, just force the most recent curve item to this value.
// Otherwise, create a node and add it.
CCurveItem *pCurve = pList->GetHead();
if (!pCurve)
{
pCurve = new CCurveItem;
if (pCurve)
{
pCurve->m_Envelope.rtStart = 0x8000000000000000; // Max negative.
pCurve->m_Envelope.rtEnd = 0x7FFFFFFFFFFFFFFF; // Max positive.
pCurve->m_Envelope.flags = 0;
pList->AddHead(pCurve);
}
else
{
LeaveCriticalSection(&m_ParamsCriticalSection);
return E_OUTOFMEMORY;
}
}
pCurve->m_Envelope.valStart = value;
pCurve->m_Envelope.valEnd = value;
pCurve->m_Envelope.iCurve = MP_CURVE_JUMP;
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_OK;
}
HRESULT CParamsManager::AddEnvelope(
DWORD dwParamIndex,
DWORD cPoints,
MP_ENVELOPE_SEGMENT *ppEnvelope)
{
V_INAME(CParams::AddEnvelope);
V_PTR_READ(ppEnvelope, *ppEnvelope);
if (dwParamIndex >= m_cParams)
return E_INVALIDARG;
if (!m_pParamInfos)
return DMUS_E_NOT_INIT;
HRESULT hr = S_OK;
EnterCriticalSection(&m_ParamsCriticalSection);
m_fDirty = TRUE;
CCurveList *pList = &m_pCurveLists[dwParamIndex];
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
DWORD dwCount;
for (dwCount = 0; dwCount < cPoints; dwCount++)
{
CCurveItem *pCurve = new CCurveItem;
if (!pCurve)
{
hr = E_OUTOFMEMORY;
break;
}
pCurve->m_Envelope = ppEnvelope[dwCount];
pCurve->m_Envelope.valEnd = ValRange(pCurve->m_Envelope.valEnd,
pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);
pCurve->m_Envelope.valStart = ValRange(pCurve->m_Envelope.valStart,
pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);
pList->AddHead(pCurve);
m_dwActiveBits |= 1 << dwParamIndex; // next call to UpdateActiveParams will ensure the parameter's value is recalculated
//TraceI(6, "DMO envelope: time %I64d-%I64d, param #%d, value %hf-%hf\n",
// pCurve->m_Envelope.rtStart, pCurve->m_Envelope.rtEnd,
// dwParamIndex, pCurve->m_Envelope.valStart, pCurve->m_Envelope.valEnd);
}
LeaveCriticalSection(&m_ParamsCriticalSection);
return hr;
}
HRESULT CParamsManager::FlushEnvelope(
DWORD dwParamIndex,
REFERENCE_TIME refTimeStart,
REFERENCE_TIME refTimeEnd)
{
if (dwParamIndex >= m_cParams)
return E_INVALIDARG;
if (!m_pParamInfos)
return DMUS_E_NOT_INIT;
if (refTimeStart >= refTimeEnd)
return E_INVALIDARG;
EnterCriticalSection(&m_ParamsCriticalSection);
m_fDirty = TRUE;
CCurveList *pList = &m_pCurveLists[dwParamIndex];
// ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
CCurveList TempList;
CCurveItem *pCurve;
while ((pCurve = pList->RemoveHead()) != 0)
{
if ((pCurve->m_Envelope.rtStart >= refTimeStart) &&
(pCurve->m_Envelope.rtEnd <= refTimeEnd))
{
delete pCurve;
}
else
{
TempList.AddHead(pCurve);
}
}
while ((pCurve = TempList.RemoveHead()) != 0)
{
pList->AddHead(pCurve);
}
LeaveCriticalSection(&m_ParamsCriticalSection);
return S_OK;
}
HRESULT CParamsManager::SetTimeFormat(
GUID guidTimeFormat,
MP_TIMEDATA mpTimeData)
{
for (DWORD dwIndex = 0; dwIndex < m_cTimeFormats; dwIndex++)
{
if (guidTimeFormat == m_pguidTimeFormats[dwIndex])
{
m_guidCurrentTimeFormat = m_pguidTimeFormats[dwIndex];
return S_OK;
}
}
return E_INVALIDARG;
}

View File

@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
// File: Param.h
//
// Desc: DirectShow sample code - definitions of CCurveItem, CCurveList,
// and CParamsManager classes.
//
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __TOOLPARAM_H__
#define __TOOLPARAM_H__
#include "medparam.h"
#include "alist.h"
typedef struct _ParamInfo
{
DWORD dwIndex; // Which parameter.
MP_PARAMINFO MParamInfo; // Standard MediaParams structure.
WCHAR * pwchText; // Array of text names for enumerated types.
} ParamInfo;
class CCurveItem : public AListItem
{
public:
CCurveItem* GetNext() { return (CCurveItem*)AListItem::GetNext();}
MP_ENVELOPE_SEGMENT m_Envelope; // Envelope segment.
};
class CCurveList : public AList
{
public:
// void Clear();
void AddHead(CCurveItem* pCurveItem) { AList::AddHead((AListItem*)pCurveItem);}
// void Insert(CCurveItem* pCurveItem);
CCurveItem* GetHead(){return (CCurveItem*)AList::GetHead();}
// CCurveItem* GetItem(LONG lIndex){return (CCurveItem*)AList::GetItem(lIndex);}
CCurveItem* RemoveHead(){ return (CCurveItem*)AList::RemoveHead();}
// void Remove(CCurveItem* pCurveItem){AList::Remove((AListItem*)pCurveItem);}
// void AddTail(CCurveItem* pCurveItem){AList::AddTail((AListItem*)pCurveItem);}
// CCurveItem* GetTail(){ return (CCurveItem*)AList::GetTail();}
~CCurveList();
};
#define MAX_REF_TIME 0x7FFFFFFFFFFFFFFF
#define MP_CAPS_ALL MP_CAPS_CURVE_JUMP | MP_CAPS_CURVE_LINEAR | MP_CAPS_CURVE_SQUARE | MP_CAPS_CURVE_INVSQUARE | MP_CAPS_CURVE_SINE
class CParamsManager : public IMediaParams, public IMediaParamInfo
{
public:
CParamsManager();
~CParamsManager();
// IUnknown
STDMETHOD(QueryInterface)(REFIID, LPVOID FAR *) PURE;
STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)() PURE;
// IMediaParams
STDMETHODIMP GetParam(DWORD dwParamIndex, MP_DATA *pValue);
STDMETHODIMP SetParam(DWORD dwParamIndex,MP_DATA value);
STDMETHODIMP AddEnvelope(DWORD dwParamIndex,DWORD cPoints,MP_ENVELOPE_SEGMENT *ppEnvelope);
STDMETHODIMP FlushEnvelope( DWORD dwParamIndex,REFERENCE_TIME refTimeStart,REFERENCE_TIME refTimeEnd);
STDMETHODIMP SetTimeFormat( GUID guidTimeFormat,MP_TIMEDATA mpTimeData);
// IMediaParamInfo
STDMETHODIMP GetParamCount(DWORD *pdwParams);
STDMETHODIMP GetParamInfo(DWORD dwParamIndex,MP_PARAMINFO *pInfo);
STDMETHODIMP GetParamText(DWORD dwParamIndex,WCHAR **ppwchText);
STDMETHODIMP GetNumTimeFormats(DWORD *pdwNumTimeFormats);
STDMETHODIMP GetSupportedTimeFormat(DWORD dwFormatIndex,GUID *pguidTimeFormat);
STDMETHODIMP GetCurrentTimeFormat( GUID *pguidTimeFormat,MP_TIMEDATA *pTimeData);
// other (non-COM) functions
HRESULT InitParams(DWORD cTimeFormats, const GUID *pguidTimeFormats, DWORD dwFormatIndex, MP_TIMEDATA mptdTimeData, DWORD cParams, ParamInfo *pParamInfos);
HRESULT GetParamFloat(DWORD dwParamIndex,REFERENCE_TIME rtTime,float *pval); // returns S_FALSE if rtTime is after the end time of the last curve
HRESULT GetParamInt (DWORD dwParamIndex,REFERENCE_TIME rt,long *pval); // returns S_FALSE if rtTime is after the end time of the last curve
HRESULT CopyParamsFromSource(CParamsManager * pSource);
// parameter control curve handling
class UpdateCallback
{
public:
// Define this in derived classes if you are going to use UpdateActiveParams.
// Called by CParamsManager inside UpdateActiveParams to update the effect's internal state variables.
// SetParamUpdate should be the same as SetParam, except that DMO defer the call to the base class
// (CParamsManager::SetParam) in SetParam but should not do so in SetParamUpdate.
virtual HRESULT SetParamUpdate(DWORD dwParamIndex, MP_DATA value) = 0;
};
// function that calls SetParam to adjust the value of all parameters that may have changed to their
// new values at time rtTime
void UpdateActiveParams(REFERENCE_TIME rtTime, UpdateCallback &rThis); // rThis should be the derived class (*this)
DWORD GetActiveParamBits() { return m_dwActiveBits; }
protected:
// data
CRITICAL_SECTION m_ParamsCriticalSection;
BOOL m_fDirty; // Has data changed since last file load or save?
DWORD m_cTimeFormats; // Number of supported time formats.
GUID *m_pguidTimeFormats; // Array of supported time formats.
GUID m_guidCurrentTimeFormat; // The time format we're set to.
MP_TIMEDATA m_mptdCurrentTimeData; // The unit of measure for the current time format.
DWORD m_cParams; // Number of parameters.
ParamInfo *m_pParamInfos; // Array of ParamInfo structures, one for each parameter.
CCurveList *m_pCurveLists; // Array of Curve lists, one for each parameter.
DWORD m_dwActiveBits; // Tracks the params that currently have curves active.
};
#endif // __TOOLPARAM_H__

View File

@@ -0,0 +1,304 @@
//------------------------------------------------------------------------------
// File: Validate.h
//
// Desc: DirectShow sample code - parameter validation macros.
//
// Copyright (c) 1997-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Summary:
//
// V_INAME(interfacename) - Set the interface name for error display
// V_STRUCTPTR_READ(ptr,type) - A dwSize struct which we will read
// V_STRUCTPTR_WRITE(ptr,type) - A dwSize struct which we will read/write
// V_PTR_READ(ptr,type) - A typed ptr w/o a dwSize which we will read
// V_PTR_WRITE(ptr,type) - A typed ptr w/o a dwSize which we will read/write
// V_PTR_WRITE_OPT(ptr,type) - An optional typed ptr w/o a dwSize which we will read/write
// V_BUFPTR_READ(ptr,size) - A variable-size buffer that we will read
// V_BUFPTR_READ_OPT(ptr,size) - An optional variable-size buffer that we will read
// V_BUFPTR_WRITE(ptr,size) - A variable-size buffer that we will read/write
// V_BUFPTR_WRITE_OPT(ptr,size) - An optional variable-size buffer that we will read/write
// V_PTRPTR_WRITE(ptrptr) - A pointer to a pointer to write to
// V_PTRPTR_WRITE_OPT(ptrptr) - A pointer to a pointer to write to that is optional
// V_PUNKOUTER(punk) - A pointer to a controlling unknown, aggregation supported
// V_PUNKOUTER_NOADD(punk) - A pointer to a controlling unknown, aggregation not supported
// V_INTERFACE(ptr) - A pointer to a COM interface
// V_INTERFACE_OPT(ptr) - An optional pointer to a COM interface
// V_REFGUID(ref) - A reference to a GUID (type REFGUID)
// V_HWND(hwnd) - A window handle
// V_HWNDOPT(hwnd) - An optional window handle
//
// For handling different versions of structures:
//
// V_STRUCTPTR_READ_VER(ptr,ver) - Begin a struct version block for read access
// At the end, 'ver' will contain the
// discovered version of the struct
// V_STRUCTPTR_READ_VER_CASE(base,ver) - Test struct against version ver of
// type 'base'.
// V_STRUCTPTR_READ_VER_END(base,ptr) - End a struct version block
//
// V_STRUCTPTR_WRITE_VER(ptr,ver) - Struct version block for write access
// V_STRUCTPTR_WRITE_VER_CASE(base,ver)
// V_STRUCTPTR_WRITE_VER_END(base,ptr)
//
// The struct version block expects type names of a base type followed by a
// numeric version, such as
//
// typedef struct { } FOO7;
// typedef struct { } FOO8;
//
// In the header FOO and LPFOO are conditionally typedef'd based on a version
// #define. The DLL will be compiled with the latest version number and hence
// the largest version of the struct.
//
// Since Windows headers are compiled by default with 8-byte alignment, adding
// one DWORD may not cause the size of the structure to change. If this happens
// you will get a 'case label already used' error on one of the VER_CASE macros.
// If this happens, you can get around it by adding a dwReserved field to the
// end of the struct to force the padding.
//
// 'optional' means the pointer is allowed to be NULL by the interface specification.
//
// Sample usage:
//
// int IDirectMusic::SetFooBarInterface(
// LPDMUS_REQUESTED_CAPS pCaps, // Caps w/ dwSize (read-only)
// LPVOID pBuffer, // Buffer we will fill in
// DWORD cbSize, // Size of the buffer
// PDIRECTMUSICBAR pBar) // Callback interface for bar on this buffer
// {
// V_INTERFACE(IDirectMusic::SetFooBarInterface);
// V_BUFPTR_WRITE(pBuffer, cbSize);
// V_INTERFACE(pBar);
// DWORD dwCapsVer; // Must be a DWORD!!!
//
// V_STRUCTPTR_READ_VER(pCaps, dwCapsVer);
// V_STRUCTPTR_READ_VER_CASE(DMUS_REQUESTED_CAPS, 7);
// V_STRUCTPTR_READ_VER_CASE(DMUS_REQUESTED_CAPS, 8);
// V_STRUCTPTR_READ_VER_END_(DMUS_REQUESTED_CAPS, pCaps);
//
// // At this point, if we are still in the function we have a valid pCaps
// // pointer and dwCapsVer is either 7 or 8, indicating the version of
// // the struct passed in.
//
// ...
// }
//
#ifndef _VALIDATE_H_
#define _VALIDATE_H_
#ifdef DBG
#include <stddef.h>
#include "debug.h"
// To turn on DebugBreak on parameter error, use the following or -DRIP_BREAK in the build:
//
//#define RIP_BREAK 1
#ifdef RIP_BREAK
#define _RIP_BREAK DebugBreak();
#else
#define _RIP_BREAK
#endif
#define V_INAME(x) \
static const char __szValidateInterfaceName[] = #x;
#define RIP_E_POINTER(ptr) \
{ Trace(-1, "%s: Invalid pointer " #ptr "\n", __szValidateInterfaceName); \
_RIP_BREAK \
return E_POINTER; }
#define RIP_E_INVALIDARG(ptr) \
{ Trace(-1, "%s: Invalid argument " #ptr "\n", __szValidateInterfaceName); \
_RIP_BREAK \
return E_INVALIDARG; }
#define RIP_E_HANDLE(h) \
{ Trace(-1, "%s: Invalid handle " #h "\n", __szValidateInterfaceName); \
_RIP_BREAK \
return E_HANDLE; }
#define RIP_W_INVALIDSIZE(ptr) \
{ Trace(-1, "%s: " #ptr "->dwSize matches no known structure size. Defaulting to oldest structure.\n", \
__szValidateInterfaceName); \
_RIP_BREAK \
}
#define RIP_E_INVALIDSIZE(ptr) \
{ Trace(-1, "%s: " #ptr "->dwSize is too small\n", __szValidateInterfaceName); \
_RIP_BREAK \
return E_INVALIDARG; }
#define RIP_E_BLOCKVSDWSIZE(ptr) \
{ Trace(-1, "%s: " #ptr " does not point to as much memory as " #ptr "->dwSize indicates\n", \
__szValidateInterfaceName); \
_RIP_BREAK \
return E_INVALIDARG; }
// NOTE: The DebugBreak() not in #ifdef is intentional - this is something that
// must be fixed in our code, not an app-generated error.
//
#define V_ASSERT(exp) \
{ if (!(exp)) { \
Trace(-1, "%s@%s: %s\n", __FILE__, __LINE__, #exp); \
DebugBreak(); }}
#else
#define V_INAME(x)
#define RIP_E_POINTER(ptr) { return E_POINTER; }
#define RIP_E_INVALIDARG(ptr) { return E_INVALIDARG; }
#define RIP_E_HANDLE(h) { return E_HANDLE; }
#define RIP_E_BLOCKVSDWSIZE(ptr) { return E_INVALIDARG; }
#define RIP_W_INVALIDSIZE(ptr)
#define RIP_E_INVALIDSIZE(ptr) { return E_INVALIDARG; }
#define V_ASSERT(exp)
#endif // DBG
// A passed struct we will only read from or may write to. Must be a struct
// with a dwSize.
//
// int foo(CFoo *pFoo)
// ...
// V_STRUCTPTR_READ(pFoo, CFoo);
// V_STRUCTPTR_WRITE(pFoo, CFoo);
//
// Use _PTR_ variants for structs w/o a dwSize
//
#define V_STRUCTPTR_READ(ptr,type) \
{ V_ASSERT(offsetof(type, dwSize) == 0); \
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
if (ptr->dwSize < sizeof(type)) RIP_E_INVALIDSIZE(ptr); \
if (IsBadReadPtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); }
#define V_STRUCTPTR_WRITE(ptr,type) \
{ V_ASSERT(offsetof(type, dwSize) == 0); \
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
if (ptr->dwSize < sizeof(type)) RIP_E_INVALIDSIZE(ptr); \
if (IsBadWritePtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); }
#define V_PTR_READ(ptr,type) \
{ if (IsBadReadPtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
#define V_PTR_WRITE(ptr,type) \
{ if (IsBadWritePtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
#define V_PTR_WRITE_OPT(ptr,type) \
{ if (ptr) if (IsBadWritePtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
// A buffer pointer with separate length (not defined by the pointer type) we will only
// read from or may write to.
//
// int foo(LPVOID *pBuffer, DWORD cbBuffer)
// ...
// V_BUFPTR_READ(pBuffer, cbBuffer);
// V_BUFPTR_WRITE(pBuffer, cbBuffer);
//
#define V_BUFPTR_READ(ptr,len) \
{ if (IsBadReadPtr(ptr, len)) RIP_E_POINTER(ptr); }
#define V_BUFPTR_READ_OPT(ptr,len) \
{ if (ptr) V_BUFPTR_READ(ptr,len); }
#define V_BUFPTR_WRITE(ptr,len) \
{ if (IsBadWritePtr(ptr, len)) RIP_E_POINTER(ptr); }
#define V_BUFPTR_WRITE_OPT(ptr,len) \
{ if (ptr) V_BUFPTR_WRITE(ptr,len); }
// A pointer to a pointer (such as a pointer to an interface pointer) to return
//
// int foo(IReturnMe **ppRet)
// ...
// V_PTRPTR_WRITE(ppRet);
// V_PTRPTR_WRITE_OPT(ppRet);
//
#define V_PTRPTR_WRITE(ptr) \
{ if (IsBadWritePtr(ptr, sizeof(void*))) RIP_E_POINTER(ptr); }
#define V_PTRPTR_WRITE_OPT(ptr) \
{ if (ptr) if (IsBadWritePtr(ptr, sizeof(void*))) RIP_E_POINTER(ptr); }
// A pointer to a controlling unknown
//
#define V_PUNKOUTER(punk) \
{ if (punk && IsBadCodePtr(punk)) RIP_E_POINTER(ptr); }
// A pointer to a controlling unknown for which we don't support aggregation
//
#define V_PUNKOUTER_NOAGG(punk) \
{ if (punk && IsBadReadPtr(punk, sizeof(IUnknown))) RIP_E_POINTER(ptr); \
if (punk) return CLASS_E_NOAGGREGATION; }
// Validate an incoming interface pointer.
//
struct _V_GENERIC_INTERFACE
{
FARPROC *(__vptr[1]);
};
#define V_INTERFACE(ptr) \
{ if (IsBadReadPtr(ptr, sizeof(_V_GENERIC_INTERFACE))) RIP_E_POINTER(ptr); \
if (IsBadReadPtr(*reinterpret_cast<_V_GENERIC_INTERFACE*>(ptr)->__vptr, sizeof(FARPROC))) \
RIP_E_POINTER(ptr); \
if (IsBadCodePtr(*(reinterpret_cast<_V_GENERIC_INTERFACE*>(ptr)->__vptr)[0])) RIP_E_POINTER(ptr); }
#define V_INTERFACE_OPT(ptr) \
{ if (ptr) V_INTERFACE(ptr); }
// Validation for a reference to a GUID, which we only ever read.
//
#define V_REFGUID(ref) \
{ if (IsBadReadPtr((void*)&ref, sizeof(GUID))) RIP_E_POINTER((void*)&ref); }
// Validation for a window handle
//
#define V_HWND(h) \
{ if (!IsWindow(h)) RIP_E_HANDLE(h); }
#define V_HWND_OPT(h) \
{ if (h) if (!IsWindow(h)) RIP_E_HANDLE(h); }
// Validation for multiple sized structs based on version
//
#define V_STRUCTPTR_READ_VER(ptr,ver) \
{ ver = 7; DWORD *pdw = &ver; \
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
if (IsBadReadPtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); \
switch ((ptr)->dwSize) {
#define V_STRUCTPTR_READ_VER_CASE(basetype,ver) \
case sizeof(basetype##ver) : \
V_ASSERT(offsetof(basetype##ver, dwSize) == 0); \
*pdw = ver; break;
#define V_STRUCTPTR_READ_VER_END(basetype,ptr) \
default : if ((ptr)->dwSize > sizeof(basetype##7)) \
{ RIP_W_INVALIDSIZE(ptr); } else \
RIP_E_INVALIDSIZE(ptr); }}
#define V_STRUCTPTR_WRITE_VER(ptr,ver) \
{ ver = 7; DWORD *pdw = &ver; \
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
if (IsBadWritePtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); \
switch ((ptr)->dwSize) {
#define V_STRUCTPTR_WRITE_VER_CASE(basetype,ver) \
case sizeof(basetype##ver) : \
V_ASSERT(offsetof(basetype##ver, dwSize) == 0); \
*pdw = ver; break;
#define V_STRUCTPTR_WRITE_VER_END(basetype,ptr) \
default : if ((ptr)->dwSize > sizeof(basetype##7)) \
{ RIP_W_INVALIDSIZE(ptr); } else \
RIP_E_INVALIDSIZE(ptr); }}
#endif // _VALIDATE_H_