/*---------------------------------------------------------------------------

    NN utility library for sample

    Copyright (C) 2002 - 2004 SEGA Corporation Library R&D Dept.
    All Rights Reserved.

    Module  : NN utility library for sample
    File    : smputil.c
    Create  : 2004/06/14
    Modify  : 2004/06/25 シェーダーロード対応
    Modify  : 2004/07/22 smpTexLoadFileOne変更
    Modify  : 2004/09/17 ライトモーション対応
    Modify  : 2004/10/07 エフェクトファイル関連追加
    Modify  : 2004/10/26 smpTexLoadFileOne変更
    Modify  : 2004/12/28 
    Modify  : 2008/11/14 smpConfigureSystemDX 関数名を smpConfigureSystemDXG20 に変更。
	                     smpConfigureSystemDXG20 関数の引数なしに変更。
						 smphWnd を static 宣言に変更。
						 マウスが機能してなかった不具合修正。
						 マウスがないときでもキー入力でアナログ値を設定するよう処理を追加。
    Modify  : 2009/01/19 smpIncludePathDispose 関数を追加。
	                     smpExitConfigureSystemDXG20 関数を追加。
						 smpDeleteSpace 関数を追加。
						 smpSetIncludePathDXG20 を追加。
						 smpIncludeCallbackDXG20 を追加。
    Modify  : 2009/01/21 smpOutputCompileShaderErrorDXG20 を追加。
	                     キーボードデバイスの協調モードの設定がバックグランドになっていたのでフォアグランドに変更した。
    Modify  : 2009/05/13 ソース整理
	                     smpClearVertexBufferInfoXB を smpClearVertexBufferInfoDXG20 に変更して頂点バッファのクリアが出来るよう修正した。
						 smpTexLoadFileOne の返り値に不具合があったので修正。
    Version : 1.18.04
    Note    : 

---------------------------------------------------------------------------*/
#define INITGUID

#if 0 /* 2008.06.10 */
#include "smpapp.h"
#else
#include <nn.h>
#include "smputil.h"
#endif

#include <stdio.h>
#include <io.h>
#include <malloc.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

#ifdef _WIN32
#include <io.h>
#include <windows.h>
#include <direct.h>
#define MKDIR(_dir)		_mkdir(_dir)
#else
#include <sys/stat.h>
#define MKDIR(_dir)		mkdir(_dir, 0755)
#endif


static IDirect3DDevice9* g_pd3dDevice;

// パフォーマンスカウンタ周波数
static	LARGE_INTEGER	smpsTmrFreq = { 0, 0 };

// バイナリファイルロードパス
static char smpsBinaryPath[MAX_PATH];

// テクスチャファイルロードパス
static char smpsTexturePath[MAX_PATH];

#define SAMPLE_BUFFER_SIZE 8
#define SAMPLE_MOUSE_BUFFER_SIZE 16

LPDIRECTINPUT8 g_pDI = NULL;         
LPDIRECTINPUTDEVICE8 g_pKeyboard = NULL;     
LPDIRECTINPUTDEVICE8 g_pMouse = NULL;     
HANDLE g_hMouseEvent;
static Sint32 dwElements = SAMPLE_MOUSE_BUFFER_SIZE;

static BYTE    diks[256];   // DirectInput keyboard state buffer 
static DIDEVICEOBJECTDATA smpOd[SAMPLE_MOUSE_BUFFER_SIZE];
static HWND smphWnd;

const SMP_KEYEMUDATA uxgDiKeyEmuDataDefault[] = {
	{SMPPAD_BTN_U, DIK_UP},
	{SMPPAD_BTN_D, DIK_DOWN},
	{SMPPAD_BTN_L, DIK_LEFT},
	{SMPPAD_BTN_R, DIK_RIGHT},
	{SMPPAD_BTN_ST, DIK_RETURN},
	{SMPPAD_BTN_A, DIK_RETURN},
	{SMPPAD_BTN_B, DIK_ESCAPE},
	{SMPPAD_BTN_B, DIK_BACKSPACE},
	{SMPPAD_BTN_TL, DIK_Q},
	{SMPPAD_BTN_TR, DIK_E},
	{SMPPAD_BTN_A, DIK_Z},
	{SMPPAD_BTN_B, DIK_X},
	{SMPPAD_BTN_X, DIK_A},
	{SMPPAD_BTN_Y, DIK_S},
};
/* パッド情報の格納場所（パッドの全入力を保持） */
SMPPAD_STATUS smpsPadStatus[SMPPAD_PORT_MAX];
HWND pdgDiHwnd;
HINSTANCE pdgDiHinst;
const SMP_KEYEMUDATA* uxgDiKeyEmuData = &uxgDiKeyEmuDataDefault[0];
long uxgDiKeyEmuDataNum = (sizeof(uxgDiKeyEmuDataDefault) / sizeof(uxgDiKeyEmuDataDefault[0]));

/**/
static Sint32 g_smpPathMax = 0;
static Sint32 g_smpPathNb = 0;
static char **g_pSmpPathList = NULL;

/*----------------------------------------------------------------------------
    関数名 : smpConfigureSystemDXG20
    機　能 : サンプルライブラリの初期化
    書　式 : void smpConfigureSystemDX(void)
    引　数 : なし
    戻り値 : なし
    説　明 : サンプルライブラリの初期化を行います
    備　考 : 
----------------------------------------------------------------------------*/
void smpConfigureSystemDXG20(void)
{
	const D3DPRESENT_PARAMETERS *pD3dpp;
	g_pd3dDevice	= (IDirect3DDevice9*)nnGetDirect3DDeviceDXG20();
	pD3dpp			= (const D3DPRESENT_PARAMETERS*)nnGetD3DPresentParametersDXG20();
	smphWnd			= pD3dpp->hDeviceWindow;

	g_smpPathMax	= 0;
	g_smpPathNb		= 0;
	g_pSmpPathList	= NULL;
}

/*----------------------------------------------------------------------------
    関数名 : smpIncludePathDispose
    機　能 : インクルードパスのメモリの解放
    書　式 : static void smpIncludePathDispose(void)
    引　数 : なし
    戻り値 : なし
    説　明 : インクルードパスのメモリを解放します
    備　考 : 
----------------------------------------------------------------------------*/
static void smpIncludePathDispose(void)
{
	Sint32 i;
	if(g_pSmpPathList != NULL){
		/* メモリの解放 */
		for(i=0; i<g_smpPathMax; i++){
			smpMemFree(g_pSmpPathList[i]);
		}
		smpMemFree(g_pSmpPathList);
		/* 初期化 */
		g_smpPathMax	= 0;
		g_smpPathNb		= 0;
		g_pSmpPathList	= NULL;
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpExitConfigureSystemDXG20
    機　能 : サンプルライブラリの終了
    書　式 : void smpExitConfigureSystemDXG20(void)
    引　数 : なし
    戻り値 : なし
    説　明 : サンプルライブラリの終了をします
    備　考 : 
----------------------------------------------------------------------------*/
void smpExitConfigureSystemDXG20(void)
{
	/* インクルードパスのメモリの解放 */
	smpIncludePathDispose();
}

/*----------------------------------------------------------------------------
    関数名 : smpPadInit
    機　能 : サンプル用パッドライブラリの初期化
    書　式 : void smpPadInit( void )
    引　数 : なし
    戻り値 : なし
    説　明 : サンプル用パッドライブラリを初期化します
    備　考 : 
----------------------------------------------------------------------------*/
void smpPadInit( void )
{
	Sint32	i;
	HRESULT hr;
	SMPPAD_STATUS* per;
	DIPROPDWORD dipdw;

	per  = smpsPadStatus;

	for(i = 0; i < SMPPAD_PORT_MAX; i++, per++){
		ZeroMemory(per,  sizeof(SMPPAD_STATUS));
	}

	hr = DirectInput8Create(	GetModuleHandle(NULL),
								DIRECTINPUT_VERSION, 
								&IID_IDirectInput8,
								(VOID**)&g_pDI,
								NULL );
	//キーボード設定
	hr = IDirectInput8_CreateDevice(g_pDI,
									&GUID_SysKeyboard,
									&g_pKeyboard,
									NULL );

	hr = IDirectInputDevice8_SetDataFormat( g_pKeyboard, &c_dfDIKeyboard ); 
	hr = IDirectInputDevice8_SetCooperativeLevel(g_pKeyboard, smphWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );

	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
	dipdw.diph.dwHow        = DIPH_DEVICE;
	dipdw.dwData            = SAMPLE_BUFFER_SIZE;
	hr = IDirectInputDevice8_SetProperty( g_pKeyboard, DIPROP_BUFFERSIZE, &dipdw.diph );
	IDirectInputDevice8_Acquire( g_pKeyboard);

	//マウス設定
	hr = IDirectInput8_CreateDevice(g_pDI,
									&GUID_SysMouse,
									&g_pMouse,
									NULL);

	if (FAILED(hr)) {
		return ;
	}

	hr = IDirectInputDevice8_SetDataFormat( g_pMouse, &c_dfDIMouse ); 
	if (FAILED(hr)) {
		return ;
	}
    hr = IDirectInputDevice8_SetCooperativeLevel(g_pMouse, smphWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
	if (FAILED(hr)) {
		switch(hr){
		case DIERR_INVALIDPARAM:
		return ;
		case DIERR_NOTINITIALIZED:
		return ;
		case E_HANDLE:
		return ;
		}
	}

	g_hMouseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	hr = IDirectInputDevice8_SetEventNotification(g_pMouse, g_hMouseEvent);
	if (FAILED(hr)) {
		return ;
	}


	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
	dipdw.diph.dwHow        = DIPH_DEVICE;
	dipdw.dwData            = SAMPLE_MOUSE_BUFFER_SIZE;
	hr = IDirectInputDevice8_SetProperty( g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph );
	IDirectInputDevice8_Acquire( g_pMouse);
		
}


/*----------------------------------------------------------------------------
    関数名 : smpPadCheck
    機　能 : サンプル用パッド情報の更新
    書　式 : void smpPadCheck( void )
    引　数 : なし
    戻り値 : なし
    説　明 : サンプル用パッド入力情報を最新にします
    備　考 :
----------------------------------------------------------------------------*/
void smpPadCheck( void )
{
	HRESULT hr;

	// keyboard
    ZeroMemory( &diks, sizeof(diks) );
    hr = IDirectInputDevice8_GetDeviceState( g_pKeyboard, sizeof(diks), &diks );
    if( hr != DI_OK ){
		hr = IDirectInputDevice8_Acquire( g_pKeyboard);
        while( hr == DIERR_INPUTLOST ) 
			hr = IDirectInputDevice8_Acquire( g_pKeyboard);
//		SetWindowText(smphWnd, "NG");
	} else {
//		SetWindowText(smphWnd, "OK");
		ConvertKeyDataToPD(&smpsPadStatus[SMPPAD_PORT1-1]);
	}

    ZeroMemory( &smpOd, sizeof(smpOd ) );
	dwElements = SAMPLE_MOUSE_BUFFER_SIZE;
    hr = IDirectInputDevice8_GetDeviceData(g_pMouse, sizeof(DIDEVICEOBJECTDATA),
                                     smpOd, (LPDWORD)&dwElements, 0);

    if( hr != DI_OK ){
		hr = IDirectInputDevice8_Acquire( g_pMouse);
        while( hr == DIERR_INPUTLOST ) 
			hr = IDirectInputDevice8_Acquire( g_pMouse);

		if( hr == DIERR_OTHERAPPHASPRIO || 
            hr == DIERR_NOTACQUIRED ) 
			;
			//SetWindowText(smphWnd, "NG");
    }



}

/*----------------------------------------------------------------------------
    関数名 : smpPadGet
    機　能 : サンプル用パッド情報の更新
    書　式 : SMPPAD_STATUS *smpPadGet( Uint32 port )
    引　数 : 取得するコントローラのポート番号( 1 〜 2 )
    戻り値 : パッド情報へのポインタ
    説　明 : パッド情報のポインタを返します
    備　考 : 内容は、smpadCheckを呼び出した時に更新されます
----------------------------------------------------------------------------*/
SMPPAD_STATUS *smpPadGet( Uint32 port )
{
	return ( &(smpsPadStatus[ port - 1 ]) );
}

/*-------------------------------------------------------------------------*/
/* キーボードバッファからPDS_PERIPHERAL構造体への変換 */
static DWORD ConvertKeyDataToPD(SMPPAD_STATUS* p)
{
	DWORD on;
	long i, num;
	const SMP_KEYEMUDATA* emu;
	Uint32 old;
	Uint32 off;
	static Sint32 msB0 = 0; 
	static Sint32 msB1 = 0; 
	Sint16 xdata,ydata;

	emu = uxgDiKeyEmuData;
	num = uxgDiKeyEmuDataNum;

	on = 0;

	for (i = 0; i < num; i++, emu++) {
		if (KEYDOWN(emu->data)) {
			on |= emu->bit;
		} else {
			on &= ~emu->bit;
		}
	}

	old = p->On;
	p->On = on;
	off = on ^ 0xffffffff;
	p->Press = (p->On ^ old) & p->On;
	p->Release = (p->On ^ old) & off;

	p->X1 = 0;
	p->Y1 = 0;
	p->X2 = 0;
	p->Y2 = 0;
	xdata = 0;
	ydata = 0;

	for( i = 0; i < dwElements; i++ ) 
    {
        switch( smpOd[ i ].dwOfs )
        {
            case DIMOFS_BUTTON0:
				if( smpOd[ i ].dwData & 0x80 ){
	                //ボタンを離す
					msB0 = 1;
				}
				else{
	                //ボタンを押す
					msB0 = 0;
				}
                break;
            case DIMOFS_BUTTON1:
				if( smpOd[ i ].dwData & 0x80 ){
	                //ボタンを離す
					msB1 = 1;
				}
				else{
	                //ボタンを押す
					msB1 = 0;
				}
                break;
            case DIMOFS_BUTTON2:
                break;
            case DIMOFS_BUTTON3:
                break;
            case DIMOFS_X:
				xdata = (Sint16)smpOd[ i ].dwData;
                break;
            case DIMOFS_Y:
				ydata = (Sint16)smpOd[ i ].dwData;
                break;
            case DIMOFS_Z:
                break;
        }
	}

	if(xdata){
		if(msB0){
			if( (xdata > 0) || (xdata < 0)){
				p->X1 = xdata * 5;
				if(p->X1 > SMPPAD_ANALOG_VALUE_MAX){
					p->X1 = SMPPAD_ANALOG_VALUE_MAX;
				}
				else if(p->X1 < -SMPPAD_ANALOG_VALUE_MAX){
					p->X1 = -SMPPAD_ANALOG_VALUE_MAX;
				}
			}
		}
		if(msB1){
			if( (xdata > 0) || (xdata < 0)){
				p->X2 = xdata * 5;
				if(p->X2 > SMPPAD_ANALOG_VALUE_MAX){
					p->X2 = SMPPAD_ANALOG_VALUE_MAX;
				}
				else if(p->X2 < -SMPPAD_ANALOG_VALUE_MAX){
					p->X2 = -SMPPAD_ANALOG_VALUE_MAX;
				}
			}
		}
	} else{
		// 2008.11.14(追加)
		// X1
		if (      KEYDOWN(DIK_NUMPAD4) )   p->X1 = -SMPPAD_ANALOG_VALUE_MAX;
		else if ( KEYDOWN(DIK_NUMPAD6) )   p->X1 =  SMPPAD_ANALOG_VALUE_MAX;
		// X2
		if (      KEYDOWN(DIK_K) )         p->X2 = -SMPPAD_ANALOG_VALUE_MAX;
		else if ( KEYDOWN(DIK_SEMICOLON) ) p->X2 =  SMPPAD_ANALOG_VALUE_MAX;
	}

	if(ydata){
		if(msB0){
			if( (ydata > 0) || (ydata < 0)){
				p->Y1 = -ydata * 5;
				if(p->Y1 > SMPPAD_ANALOG_VALUE_MAX){
					p->Y1 = SMPPAD_ANALOG_VALUE_MAX;
				}
				else if(p->Y1 < -SMPPAD_ANALOG_VALUE_MAX){
					p->Y1 = -SMPPAD_ANALOG_VALUE_MAX;
				}
			}
		}
		if(msB1){
			if( (ydata > 0) || (ydata < 0)){
				p->Y2 = -ydata * 5;
				if(p->Y2 > SMPPAD_ANALOG_VALUE_MAX){
					p->Y2 = SMPPAD_ANALOG_VALUE_MAX;
				}
				else if(p->Y2 < -SMPPAD_ANALOG_VALUE_MAX){
					p->Y2 = -SMPPAD_ANALOG_VALUE_MAX;
				}
			}
		}
	} else{
		// 2008.11.14(追加)
		// Y1
		if (      KEYDOWN(DIK_NUMPAD2) ) p->Y1 = -SMPPAD_ANALOG_VALUE_MAX;
		else if ( KEYDOWN(DIK_NUMPAD8) ) p->Y1 =  SMPPAD_ANALOG_VALUE_MAX;
		// Y2
		if (      KEYDOWN(DIK_L) )       p->Y2 = -SMPPAD_ANALOG_VALUE_MAX;
		else if ( KEYDOWN(DIK_O) )       p->Y2 =  SMPPAD_ANALOG_VALUE_MAX;
	}

	return on;
}

/*----------------------------------------------------------------------------
    関数名 : smpMemAlloc
    機　能 : メモリアロケーション
    書　式 : void *smpMemAlloc( Uint32 size )
    引　数 : 確保するメモリのサイズ(byte)
    戻り値 : 確保したメモリの先頭へのポインタ
    説　明 : mallocを使用してメモリを確保します
    備　考 : DXG20 では NNS_MATRIX, NNS_MATRIX44 が align(16) されているので必要
----------------------------------------------------------------------------*/
void *smpMemAlloc( Uint32 size )
{

	return _aligned_offset_malloc( size, 16, 0);
	//return( malloc( size ) );
}

/*----------------------------------------------------------------------------
    関数名 : smpMemFree
    機　能 : メモリの解放
    書　式 : void smpMemFree( void *ptr )
    引　数 : 解放するメモリのへのポインタ
    戻り値 : なし
    説　明 : mallocを使用して確保したメモリを解放します
    備　考 : DXG20 では NNS_MATRIX, NNS_MATRIX44 が align(16) されているので必要
----------------------------------------------------------------------------*/
void smpMemFree( void *ptr )
{
	if( ptr )
		_aligned_free( ptr );
}

/*----------------------------------------------------------------------------
    関数名 : smpMemCopy
    機　能 : メモリコピー
    書　式 : void smpMemCopy( void *dst, const void *src, Uint32 size )
    引　数 : dst  : コピー先メモリのへのポインタ
    　　　   src  : コピー元メモリのへのポインタ
    　　　   size : コピーするメモリのサイズ(byte)
    戻り値 : なし
    説　明 : memcpyを使用してメモリをコピーします
    備　考 : 
----------------------------------------------------------------------------*/
void smpMemCopy( void *dst, const void *src, Uint32 size )
{
	CopyMemory( dst, src, size );
}

/*----------------------------------------------------------------------------
    関数名 : smpMemSet
    機　能 : メモリセット
    書　式 : void smpMemSet( void *dst, Uint8 src, Uint32 size )
    引　数 : dst  : メモリへのポインタ
    　　　   src  : セットする値
    　　　   size : セットするメモリのサイズ(byte)
    戻り値 : なし
    説　明 : memsetを使用してメモリにsrcをセットします
    備　考 : 
----------------------------------------------------------------------------*/
void smpMemSet( void *dst, Uint8 src, Uint32 size )
{
	FillMemory( dst, size, src );
}

/*----------------------------------------------------------------------------
    関数名 : void SwapEndianCnkFileHader(NNS_BINCNK_FILEHEADER* pHader)
    機　能 : チャンクファイルヘッダのエディアンを変換します
    書　式 : void	SwapEndianCnkNOf0Hader(NNS_BINCNK_NOF0HEADER* pHader)
    引　数 : なし
    戻り値 : なし
    説　明 :チャンクファイルヘッダのエディアンを変換します
    備　考 : 
----------------------------------------------------------------------------*/
static void SwapEndianCnkFileHader(NNS_BINCNK_FILEHEADER* pHader)
{

	// pHader->Id			= _SW32(pHader->Id);
	// pHader->OfsNextId	= _SW32(pHader->OfsNextId);
	pHader->nChunk		= _SW32(pHader->nChunk);
	pHader->OfsData		= _SW32(pHader->OfsData);
	pHader->SizeData	= _SW32(pHader->SizeData);
	pHader->OfsNOF0		= _SW32(pHader->OfsNOF0);
	pHader->SizeNOF0	= _SW32(pHader->SizeNOF0);
	pHader->Version		= _SW32(pHader->Version);

}

/*----------------------------------------------------------------------------
    関数名 : void SwapEndianCnkDataHader(NNS_BINCNK_DATAHEADER* pHader)
    機　能 : チャンクデータヘッダのエディアンを変換します
    書　式 : void	SwapEndianCnkNOf0Hader(NNS_BINCNK_NOF0HEADER* pHader)
    引　数 : なし
    戻り値 : なし
    説　明 :チャンクデータヘッダのエディアンを変換します
    備　考 : 
----------------------------------------------------------------------------*/
static void SwapEndianCnkDataHader(NNS_BINCNK_DATAHEADER* pHader)
{

	// pHader->Id			= _SW32(pHader->Id);
	// pHader->OfsNextId	= _SW32(pHader->OfsNextId);
	pHader->OfsMainData	= _SW32(pHader->OfsMainData);
	pHader->Version		= _SW32(pHader->Version);
	
}

/*----------------------------------------------------------------------------
    関数名 : void	SwapEndianCnkNOf0Hader(NNS_BINCNK_NOF0HEADER* pHader)
    機　能 : チャンクアドレス解消ヘッダのエディアンを変換します
    書　式 : void	SwapEndianCnkNOf0Hader(NNS_BINCNK_NOF0HEADER* pHader)
    引　数 : なし
    戻り値 : なし
    説　明 : チャンクアドレス解消ヘッダのエディアンを変換します
    備　考 : 
----------------------------------------------------------------------------*/
static void	SwapEndianCnkNOf0Hader(NNS_BINCNK_NOF0HEADER* pHader)
{

	Uint32* pTgt;
	int		i;

	// pHader->Id			= _SW32(pHader->Id);
	// pHader->OfsNextId	= _SW32(pHader->OfsNextId);
	pHader->nData		= _SW32(pHader->nData);
	pHader->Pad			= _SW32(pHader->Pad);

	pTgt = (Uint32*)(pHader + 1);
	for(i=0; i<pHader->nData; i++){
		pTgt[i] = _SW32(pTgt[i]);
	}

}

/*----------------------------------------------------------------------------
    関数名 : smpTmrInit
    機　能 : サンプル用タイマライブラリの初期化
    書　式 : void smpTmrInit( void )
    引　数 : なし
    戻り値 : なし
    説　明 : サンプル用タイマライブラリを初期化します
    備　考 : 
----------------------------------------------------------------------------*/
void smpTmrInit( void )
{
	QueryPerformanceFrequency( &smpsTmrFreq );
}

/*----------------------------------------------------------------------------
    関数名 : smpTmrGet
    機　能 : フリーランタイマを取得する
    書　式 : Uint32 smpTmrGet( void )
    引　数 : なし
    戻り値 : フリーラン増加タイマ値（microsecond）
    説　明 : フリーランタイマ値を取得します
    備　考 : この関数とsmpTmrDiff関数を組み合わせて、区間の時間を測定します
----------------------------------------------------------------------------*/
Uint32 smpTmrGet( void )
{
	LARGE_INTEGER	cnt;

	QueryPerformanceCounter( &cnt );

	return (Uint32)cnt.LowPart;
}

/*----------------------------------------------------------------------------
    関数名 : smpTmrDiff
    機　能 : フリーランタイマ値の差分を求め、microsecondで返します
    書　式 : Uint32 smpTmrDiff( Uint32 time1, Uint32 time0 )
    引　数 : time1 フリーランタイマ値1
             time0 フリーランタイマ値0
    戻り値 : タイマ値0からタイマ値1までの経過時間
    説　明 : タイマ値0からタイマ値1までの経過時間を返します
    備　考 : smpTmrGet関数で取得したタイマ値間の差分を求めます
----------------------------------------------------------------------------*/
Uint32 smpTmrDiff( Uint32 time1, Uint32 time0 )
{
	Float	msec;

	msec = (Float)(time1 - time0) * 1000.f * 1000.f / (Float)smpsTmrFreq.QuadPart;

	return (Uint32)msec;
}

/*----------------------------------------------------------------------------
    関数名 : smpGetFileSize
    機　能 : ファイルサイズの取得
    書　式 : Uint32 smpBinGetFileSize( char *sFile )
    引　数 : sFile ファイル名
    戻り値 : サイズ　失敗0
    説　明 : ファイルサイズを取得します
    備　考 : 
----------------------------------------------------------------------------*/
Uint32 smpGetFileSize( char *sFile )
{
	FILE	*fp;
	Sint32	size;

	if( (fp = fopen( sFile, "rb" ) ) == NULL )
		return 0;

	size = _filelength( _fileno( fp ) );
	if( size < 0 )
		size = 0;

	fclose( fp );
	
	return (Uint32)size;
}

/*----------------------------------------------------------------------------
    関数名 : smpReadFile
    機　能 : ファイルを読み込みます
    書　式 : Sint32 smpBinReadFile( char *sFile, void *pBuf )
    引　数 : sFile 読み込むファイル名
             pBuf  読み込む先のポインタ
    戻り値 : なし
    説　明 : ファイルの内容を指定されたポインタへ読み込みます
    備　考 : 
----------------------------------------------------------------------------*/
void smpReadFile( char *sFile, void *pBuf )
{
	FILE	*fp;
	Sint32	size;

	if( (fp = fopen( sFile, "rb" ) ) == NULL )
		return;

	size = _filelength( _fileno( fp ) );
	if( size < 0 )
	{
		fclose( fp );
		return;
	}

	if( fread( pBuf, size, 1, fp ) != 1 )
	{
		fclose( fp );
		return;
	}

	fclose( fp );
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetFilePath
    機　能 : バイナリファイルロードパス設定
    書　式 : void smpBinSetFilePath( const char *sPath )
    引　数 : sPath : バイナリファイルロードパス
    戻り値 : なし
    説　明 : バイナリファイルをロードするためのパスを設定します
    備　考 : 
----------------------------------------------------------------------------*/
void smpBinSetFilePath( const char *sPath )
{
	strcpy( smpsBinaryPath, (char *)sPath );
}

/*----------------------------------------------------------------------------
    関数名 : smpBinGetFileSize
    機　能 : ファイルサイズの取得
    書　式 : Uint32 smpBinGetFileSize( char *sFile )
    引　数 : sFile ファイル名
    戻り値 : サイズ　失敗0
    説　明 : ファイルサイズを取得します
    備　考 : 
----------------------------------------------------------------------------*/
Uint32 smpBinGetFileSize( char *sFile )
{
	FILE	*fp;
	Sint32	size;
	char	filename[MAX_PATH];

	strcpy( filename, smpsBinaryPath );
	strcat( filename, sFile );

	if( (fp = fopen( filename, "rb" ) ) == NULL )
		return 0;

	size = _filelength( _fileno( fp ) );
	if( size < 0 )
		size = 0;

	fclose( fp );
	
	return (Uint32)size;
}

/*----------------------------------------------------------------------------
    関数名 : smpBinReadFile
    機　能 : ファイルを読み込みます
    書　式 : Sint32 smpBinReadFile( char *sFile, void *pBuf )
    引　数 : sFile 読み込むファイル名
             pBuf  読み込む先のポインタ
    戻り値 : なし
    説　明 : ファイルの内容を指定されたポインタへ読み込みます
    備　考 : 
----------------------------------------------------------------------------*/
void smpBinReadFile( char *sFile, void *pBuf )
{
	FILE	*fp;
	Sint32	size;
	char	filename[MAX_PATH];

	strcpy( filename, smpsBinaryPath );
	strcat( filename, sFile );

	if( (fp = fopen( filename, "rb" ) ) == NULL )
		return;

	size = _filelength( _fileno( fp ) );
	if( size < 0 )
	{
		fclose( fp );
		return;
	}

	if( fread( pBuf, size, 1, fp ) != 1 )
	{
		fclose( fp );
		return;
	}

	fclose( fp );
}

/*----------------------------------------------------------------------------
    関数名 : smpBinResolvePointer
    機　能 : バイナリデータアドレス解決
    書　式 : void smpBinResolvePointer( NNS_BINCNK_DATAHEADER *pData, NNS_BINCNK_NOF0HEADER *pNOF0 )
    引　数 : pData バイナリデータの先頭アドレス
             pNOFo アドレス解決用データの先頭アドレス
    戻り値 : なし
    説　明 : チャンクデータ内のポインタ参照をしているデータの
             アドレス解決を行います
    備　考 : 
----------------------------------------------------------------------------*/
#pragma warning( disable : 4311 )
void smpBinResolvePointer( NNS_BINCNK_DATAHEADER *pData, NNS_BINCNK_NOF0HEADER *pNOF0 )
{
	Sint32	i, nData;
	Uint32	*pDst, *pSrc;
	Uint32	Offset, TopAddr;

	nData = pNOF0->nData;			// 解決するアドレスデータ数
	pDst  = (Uint32 *)pData;		// アドレス解決する対象（バイナリデータ先頭）
	pSrc  = (Uint32 *)(pNOF0 + 1);	// アドレス解決用オフセットデータ先頭
	TopAddr = (Uint32)pData;		// 補正するアドレスオフセット値

	for( i = 0; i < nData; i++ )
	{
		Offset = *pSrc++ >> 2;
		pDst[Offset] = TopAddr + _SW32(pDst[Offset]);
	}
}
#pragma warning( default : 4311 )

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpObject
    機　能 : オブジェクト、テクスチャデータアドレス取得
    書　式 : void smpBinSetUpObject( NNS_OBJECT **pObj, NNS_TEXFILELIST **pTexFileList, void *pBuf )
    引　数 : pObj         解決されたオブジェクト構造体のアドレス格納先
    　　　   pTexFileList 解決されたテクスチャファイルリスト構造体のアドレス格納先
    　　　   pBuf         チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             オブジェクト、テクスチャリストデータへのアドレスを返します
    備　考 : オブジェクト、テクスチャリストデータが存在しない場合は
             何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpObject( NNS_OBJECT **pObj, NNS_TEXFILELIST **pTexFileList, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if((pObj == NULL) && (pTexFileList == NULL)){
		return;
	}
	else{
		if(pObj){
			*pObj = NULL;
		}
		if(pTexFileList){
			*pTexFileList = NULL;
		}
	}

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_TEXTURE_DXG20) )
		{
			if( pTexFileList )
				*pTexFileList = (NNS_TEXFILELIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianTexture(*pTexFileList);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_OBJECT_DXG20) )
		{
			if( pObj )
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
				//現在はこの関数を入れておくがVer1.12.00以降出力されたオブジェクトは必要ない
				smpClearVertexBufferInfoDXG20( *pObj );
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMotion
    機　能 : モーションデータアドレス取得
    書　式 : void smpBinSetUpMotion( NNS_MOTION **pMotion, void *pBuf )
    引　数 : pMotion  解決されたモーション構造体のアドレス格納先
             pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             モーションデータへのアドレスを返します
    備　考 : モーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMotion( NNS_MOTION **pMotion, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( (pData->Id == _SW32(NND_CHUNK_MOTION_DXG20))
		 || (pData->Id == _SW32(NND_CHUNK_CAMERA_MOTION_DXG20)) )
		{
			if( pMotion )
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMorphMotion
    機　能 : モーフモーションデータアドレス取得
    書　式 : void smpBinSetUpMorphMotion( NNS_MOTION **pMotion, void *pBuf )
    引　数 : pMotion  解決されたモーフモーション構造体のアドレス格納先
             pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             モーフモーションデータへのアドレスを返します
    備　考 : モーフモーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMorphMotion( NNS_MOTION **pMotion, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MORPH_MOTION_DXG20) )
		{
			if( pMotion )
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMorphTargetList
    機　能 : モーフターゲットデータアドレス取得
    書　式 : void smpBinSetUpMorphTargetList( NNS_MORPHTARGETLIST **MorphTargetList, void *pBuf )
    引　数 : MorphTargetList 解決されたモーフターゲットリスト構造体のアドレス格納先
             pBuf    		 チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             モーフターゲットリストデータへのアドレスを返します
    備　考 : モーフターゲットリストデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMorphTargetList( NNS_MORPHTARGETLIST **MorphTargetList, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(MorphTargetList == NULL){
		return;
	}
	*MorphTargetList = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MORPH_DXG20) )
		{
			if( MorphTargetList )
				*MorphTargetList = (NNS_MORPHTARGETLIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMorphTarget(*MorphTargetList);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpNodeNameList
    機　能 : ノードネームリストアドレス取得
    書　式 : void smpBinSetUpNodeNameList( NNS_NODENAMELIST **pNodeNameList, void *pBuf )
    引　数 : pNodeNameList : 解決されたノードネームリスト構造体のアドレス格納先
    　　　   pBuf          : チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
    　　　   ノードネームリストデータへのアドレスを返します
    備　考 : ノードネームリストデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpNodeNameList( NNS_NODENAMELIST **pNodeNameList, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pNodeNameList == NULL){
		return;
	}
	*pNodeNameList = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_NODE_NAME_DXG20) )
		{
			if( pNodeNameList )
			{
				*pNodeNameList = (NNS_NODENAMELIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianNodeName(*pNodeNameList);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpLightPtr
    機　能 : ライトポインタアドレス取得
    書　式 : void smpBinSetUpLightPtr( NNS_LIGHTPTR **LightPtr, void *pBuf )
    引　数 : LightPtr 	解決されたライトポインタ構造体のアドレス格納先
             pBuf   	チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             ライトポインタへのアドレスを返します
    備　考 : ライトポインタが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpLightPtr( NNS_LIGHTPTR **LightPtr, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if( LightPtr  == NULL){
		return;
	}
	*LightPtr = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_DXG20) )
		{
			if( LightPtr )
			{
				*LightPtr = (NNS_LIGHTPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianLight(*LightPtr);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpCameraPtr
    機　能 : カメラポインタアドレス取得
    書　式 : void smpBinSetUpCameraPtr( NNS_CAMERAPTR **CameraPtr, void *pBuf )
    引　数 : CameraPtr 	解決されたカメラポインタ構造体のアドレス格納先
             pBuf   	チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             カメラポインタへのアドレスを返します
    備　考 : カメラポインタが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpCameraPtr( NNS_CAMERAPTR **CameraPtr, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(CameraPtr == NULL){
		return;
	}
	*CameraPtr = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_DXG20) )
		{
			if( CameraPtr )
			{
				*CameraPtr = (NNS_CAMERAPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianCamera(*CameraPtr);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpCameraMotion
    機　能 : カメラポインタ、カメラモーションアドレス取得
    書　式 : void smpBinSetUpCameraMotion( NNS_CAMERAPTR **CameraPtr, NNS_MOTION **pMotion, void *pBuf )
    引　数 : CameraPtr 	解決されたカメラポインタ構造体のアドレス格納先
             pMotion    解決されたモーション構造体のアドレス格納先
             pBuf   	チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             カメラポインタへのアドレスとカメラモーションへのアドレスを返します。
             データが存在しない場合、NULLを返します。
    備　考 : カメラポインタ、またはが存在しない場合は何も行わず終了します。
----------------------------------------------------------------------------*/
void smpBinSetUpCameraMotion( NNS_CAMERAPTR **CameraPtr, NNS_MOTION **pMotion, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if((CameraPtr == NULL) && (pMotion == NULL)){
		return;
	}
	else{
		if(CameraPtr){
			*CameraPtr = NULL;
		}
		if(pMotion){
			*pMotion = NULL;
		}
	}

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_DXG20) )
		{
			if( CameraPtr )
			{
				*CameraPtr = (NNS_CAMERAPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianCamera(*CameraPtr);
			}
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_MOTION_DXG20) )
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else		
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMaterialMotion
    機　能 : マテリアルモーションデータアドレス取得
    書　式 : void smpBinSetUpMaterialMotion( NNS_MOTION **pMotion, void *pBuf )
    引　数 : pMotion  解決されたモーション構造体のアドレス格納先
             pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             モーションデータへのアドレスを返します
    備　考 : モーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMaterialMotion( NNS_MOTION **pMotion, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if(pData->Id == _SW32(NND_CHUNK_MATERIAL_MOTION_DXG20))
		{
			if( pMotion )
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpNodeTreeObject
    機　能 : ノードツリーオブジェクトデータアドレス取得
    書　式 : void smpBinSetUpNodeTreeObject( NNS_OBJECT **pObj, void *pBuf )
    引　数 : pObj     解決されたノードツリーオブジェクト構造体のアドレス格納先
             pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             ノードツリーオブジェクトデータへのアドレスを返します
    備　考 : ノードツリーオブジェクトデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpNodeTreeObject( NNS_OBJECT **pObj, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pObj == NULL){
		return;
	}
	*pObj = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_NODE_TREE_OBJECT_DXG20) )
		{
			if( pObj )
			{
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMeshObject
    機　能 : メッシュオブジェクトデータアドレス取得
    書　式 : void smpBinSetUpMeshObject( NNS_OBJECT **pObj, void *pBuf )
    引　数 : pObj     解決されたメッシュオブジェクト構造体のアドレス格納先
             pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             メッシュオブジェクトデータへのアドレスを返します
    備　考 : メッシュオブジェクトデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMeshObject( NNS_OBJECT **pObj, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if(pObj == NULL){
		return;
	}
	*pObj = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MESH_OBJECT_DXG20) )
		{
			if( pObj )
			{
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpLightMotion
    機　能 : ライトポインタ、ライトモーションデータアドレス取得
    書　式 : void smpBinSetUpMotion( NNS_LIGHTPTR **pLightPtr, NNS_MOTION **pMotion, void *pBuf )
    引　数 : pLightPtr	解決されたライトポインタ構造体のアドレス格納先
             pMotion	解決されたモーション構造体のアドレス格納先
             pBuf		チャンクバイナリデータの格納先アドレス
    戻り値 : なし
    説　明 : チャンクバイナリデータのアドレス解決を行いデータ内に含まれる
             ライトポインタへのアドレスとライトモーションデータへのアドレスを返します
    備　考 : ライトポインタ、またはモーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpLightMotion( NNS_LIGHTPTR **pLightPtr, NNS_MOTION **pMotion, void *pBuf )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;

	if((pLightPtr == NULL) && (pMotion == NULL)){
		return;
	}
	else{
		if(pLightPtr){
			*pLightPtr = NULL;
		}
		if(pMotion){
			*pMotion = NULL;
		}
	}

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBuf + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBuf + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_DXG20) )
		{
			if( pLightPtr )
			{
				*pLightPtr = (NNS_LIGHTPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianLight(*pLightPtr);
			}
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_MOTION_DXG20) )
		{
			if( pMotion )
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpObjectCopy
    機　能 : オブジェクト、テクスチャデータアドレス取得
    書　式 : void smpBinSetUpObjectCopy( NNS_OBJECT **pObj, NNS_TEXFILELIST **pTexFileList, void *pBufDst, void *pBufSrc )
    引　数 : pObj         解決されたオブジェクト構造体のアドレス格納先
             pTexFileList 解決されたテクスチャファイルリスト構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             オブジェクト、テクスチャファイルリストデータへのアドレスを返します
    備　考 : オブジェクト、テクスチャファイルリストデータが存在しない場合は
             何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpObjectCopy( NNS_OBJECT **pObj, NNS_TEXFILELIST **pTexFileList, void *pBufDst, void *pBufSrc)
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if((pObj == NULL) && (pTexFileList == NULL)){
		return;
	}
	else{
		if(pObj){
			*pObj = NULL;
		}
		if(pTexFileList){
			*pTexFileList = NULL;
		}
	}
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_TEXTURE_DXG20) )
		{
			if( pTexFileList )
			{
				*pTexFileList = (NNS_TEXFILELIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianTexture(*pTexFileList);
			}
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_OBJECT_DXG20) )
		{
			if( pObj )
			{
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
				//現在はこの関数を入れておくがVer1.12.00以降出力されたオブジェクトは必要ない
				smpClearVertexBufferInfoDXG20( *pObj );
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMotionCopy
    機　能 : モーションデータアドレス取得
    書　式 : void smpBinSetUpMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
    引　数 : pMotion  解決されたモーション構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             モーションデータへのアドレスを返します
    備　考 : モーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if(( pData->Id == _SW32(NND_CHUNK_MOTION_DXG20 ) || ( pData->Id == NND_CHUNK_CAMERA_MOTION_DXG20) ))
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMorphMotionCopy
    機　能 : モーフモーションデータアドレス取得
    書　式 : void smpBinSetUpMorphMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
    引　数 : pMotion  解決されたモーフモーション構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             モーフモーションデータへのアドレスを返します
    備　考 : モーフモーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMorphMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MORPH_MOTION_DXG20) )
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMorphTargetListCopy
    機　能 : モーフターゲットデータアドレス取得
    書　式 : void smpBinSetUpMorphTargetListCopy( NNS_MORPHTARGETLIST **MorphTargetList, void *pBufDst, void *pBufSrc )
    引　数 : MorphTargetList  解決されたモーフターゲットリスト構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             モーフターゲットリストデータへのアドレスを返します
    備　考 : モーフターゲットリストデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMorphTargetListCopy( NNS_MORPHTARGETLIST **MorphTargetList, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(MorphTargetList == NULL){
		return;
	}
	*MorphTargetList = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MORPH_DXG20) )
		{
			if( MorphTargetList )
			{
				*MorphTargetList = (NNS_MORPHTARGETLIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMorphTarget(*MorphTargetList);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpNodeNameListCopy
    機　能 : ノードネームリストアドレス取得
    書　式 : void smpBinSetUpNodeNameListCopy( NNS_NODENAMELIST **pNodeNameList, void *pBufDst, void *pBufSrc )
    引　数 : MorphTargetList  解決されたノードネームリスト構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             ノードネームリストデータへのアドレスを返します
    備　考 : ノードネームリストデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpNodeNameListCopy( NNS_NODENAMELIST **pNodeNameList, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pNodeNameList == NULL){
		return;
	}
	*pNodeNameList = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_NODE_NAME_DXG20) )
		{
			if( pNodeNameList )
			{
				*pNodeNameList = (NNS_NODENAMELIST *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianNodeName(*pNodeNameList);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpLightPtrCopy
    機　能 : ライトポインタアドレス取得
    書　式 : void smpBinSetUpLightPtrCopy( NNS_LIGHTPTR **LightPtr, void *pBufDst, void *pBufSrc )
    引　数 : LightPtr      解決されたライトポインタ構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             ライトポインタへのアドレスを返します
    備　考 : ライトポインタが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpLightPtrCopy( NNS_LIGHTPTR **LightPtr, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(LightPtr == NULL){
		return;
	}
	*LightPtr = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_DXG20) )
		{
			if( LightPtr )
			{
				*LightPtr = (NNS_LIGHTPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianLight(*LightPtr);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpCameraPtrCopy
    機　能 : カメラポインタアドレス取得
    書　式 : void smpBinSetUpCameraPtrCopy( NNS_CAMERAPTR **CameraPtr, void *pBufDst, void *pBufSrc )
    引　数 : CameraPtr    解決されたカメラポインタ構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             カメラポインタへのアドレスを返します
    備　考 : カメラポインタが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpCameraPtrCopy( NNS_CAMERAPTR **CameraPtr, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(CameraPtr == NULL){
		return;
	}
	*CameraPtr = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_DXG20) )
		{
			if( CameraPtr )
			{
				*CameraPtr = (NNS_CAMERAPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianCamera(*CameraPtr);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpCameraMotionCopy
    機　能 : カメラポインタ、カメラモーションアドレス取得
    書　式 : void smpBinSetUpCameraMotionCopy( NNS_CAMERAPTR **CameraPtr, NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
    引　数 : CameraPtr    解決されたカメラポインタ構造体のアドレス格納先
             pMotion      解決されたモーション構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             カメラポインタへのアドレスとカメラモーションへのアドレスを返します。
    備　考 : カメラポインタ、またはが存在しない場合は何も行わず終了します。
----------------------------------------------------------------------------*/
void smpBinSetUpCameraMotionCopy( NNS_CAMERAPTR **CameraPtr, NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if((CameraPtr == NULL) && (pMotion == NULL)){
		return;
	}
	else{
		if(CameraPtr){
			*CameraPtr = NULL;
		}
		if(pMotion){
			*pMotion = NULL;
		}
	}
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_DXG20) )
		{
			if( CameraPtr )
			{
				*CameraPtr = (NNS_CAMERAPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianCamera(*CameraPtr);
			}
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_CAMERA_MOTION_DXG20) )
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else		
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMaterialMotionCopy
    機　能 : マテリアルモーションデータアドレス取得
    書　式 : void smpBinSetUpMaterialMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
    引　数 : pMotion  解決されたマテリアルモーション構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             マテリアルモーションデータへのアドレスを返します
    備　考 : マテリアルモーションデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMaterialMotionCopy( NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pMotion == NULL){
		return;
	}
	*pMotion = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MATERIAL_MOTION_DXG20) )
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpNodeTreeObjectCopy
    機　能 : ノードツリーオブジェクトデータアドレス取得
    書　式 : void smpBinSetUpNodeTreeObjectCopy( NNS_OBJECT **pObj, void *pBufDst, void *pBufSrc )
    引　数 : pObj         解決されたノードツリーオブジェクト構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             ノードツリーオブジェクトデータへのアドレスを返します
    備　考 : ノードツリーオブジェクトデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpNodeTreeObjectCopy( NNS_OBJECT **pObj, void *pBufDst, void *pBufSrc)
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pObj == NULL){
		return;
	}
	*pObj = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_NODE_TREE_OBJECT_DXG20) )
		{
			if( pObj )
			{
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpMeshObjectCopy
    機　能 : メッシュオブジェクトデータアドレス取得
    書　式 : void smpBinSetUpMeshObjectCopy( NNS_OBJECT **pObj, void *pBufDst, void *pBufSrc )
    引　数 : pObj         解決されたメッシュオブジェクト構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             メッシュオブジェクトデータへのアドレスを返します
    備　考 : メッシュオブジェクトデータが存在しない場合は何も行わず終了します
----------------------------------------------------------------------------*/
void smpBinSetUpMeshObjectCopy( NNS_OBJECT **pObj, void *pBufDst, void *pBufSrc)
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if(pObj == NULL){
		return;
	}
	*pObj = NULL;
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_MESH_OBJECT_DXG20) )
		{
			if( pObj )
			{
				*pObj = (NNS_OBJECT *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianObject(*pObj);
			}
			return;
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinSetUpLightMotionCopy
    機　能 : ライトポインタ、ライトモーションアドレス取得
    書　式 : void smpBinSetUpLightMotionCopy( NNS_LIGHTPTR **LightPtr, NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
    引　数 : LightPtr    解決されたライトポインタ構造体のアドレス格納先
             pMotion      解決されたモーション構造体のアドレス格納先
             pBufDst      チャンクバイナリデータの格納先アドレス(デスト)
             pBufSrc      チャンクバイナリデータの格納先アドレス(ソース)
    戻り値 : なし
    説　明 : チャンクバイナリデータをコピーしアドレス解決を行いデータ内に含まれる
             ライトポインタへのアドレスとライトモーションへのアドレスを返します。
    備　考 : ライトポインタ、またはが存在しない場合は何も行わず終了します。
----------------------------------------------------------------------------*/
void smpBinSetUpLightMotionCopy( NNS_LIGHTPTR **pLightPtr, NNS_MOTION **pMotion, void *pBufDst, void *pBufSrc )
{
	Sint32		i, nCnk;
	Uint8		*pTopBuf;
	NNS_BINCNK_FILEHEADER	*pHeader;
	NNS_BINCNK_DATAHEADER	*pData;
	NNS_BINCNK_NOF0HEADER	*pNOF0;
	Uint32 DataSize;

	if((pLightPtr == NULL) && (pMotion == NULL)){
		return;
	}
	else{
		if(pLightPtr){
			*pLightPtr = NULL;
		}
		if(pMotion){
			*pMotion = NULL;
		}
	}
	
	pHeader = (NNS_BINCNK_FILEHEADER *)pBufSrc;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return;
	}

	nCnk = pHeader->nChunk;				// バイナリデータ数
										// バイナリデータ先頭
	pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)pBufSrc + pHeader->OfsData);
	pTopBuf = (Uint8 *)pData;
										// NOF0データ先頭
	pNOF0 = (NNS_BINCNK_NOF0HEADER *)((Uint8 *)pBufSrc + pHeader->OfsNOF0);
	SwapEndianCnkNOf0Hader(pNOF0);		// エディアン変換

	//データサイズ取得
	DataSize = (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData);
	//データコピー
	memcpy( pBufDst, pTopBuf, DataSize);
	pData = (NNS_BINCNK_DATAHEADER *)pBufDst;
	pTopBuf = (Uint8 *)pData;

	// アドレス解決
	smpBinResolvePointer( pData, pNOF0 );

	// 含まれるバイナリデータの判別とアドレス取得
	for( i = 0; i < nCnk; i++ )
	{
		SwapEndianCnkDataHader(pData);
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_DXG20) )
		{
			if( pLightPtr )
			{
				*pLightPtr = (NNS_LIGHTPTR *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianLight(*pLightPtr);
			}
		}
		else
		if( pData->Id == _SW32(NND_CHUNK_LIGHT_MOTION_DXG20) )
		{
			if( pMotion )
			{
				*pMotion = (NNS_MOTION *)(pTopBuf + pData->OfsMainData);
				nnbSwapEndianMotion(*pMotion);
			}
			return;
		}
		else		
		if( pData->Id == _SW32(NND_CHUNK_NEND_DXG20) )
		{
			return;
		}

		// 次のバイナリデータ
		// （次の識別文字までのバイト数(OfsNextId)は、
		//   直後のメンバ変数(OfsMainData)からのオフセット値である）
		pData = (NNS_BINCNK_DATAHEADER *)((Uint8 *)&pData->OfsMainData + pData->OfsNextId);
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpBinGetBinaryDataSize
    機　能 : チャンクバイナリデータサイズの取得
    書　式 : Uint32 smpBinGetBinaryDataSize( void *pBuf )
    引　数 : pBuf     チャンクバイナリデータの格納先アドレス
    戻り値 : 実データサイズ（バイト）データ不正（0）
    説　明 : チャンクバイナリデータのヘッダ、NOF0以外の実データ部分のバイトサイズを
             取得します
    備　考 : 
----------------------------------------------------------------------------*/
Uint32 smpBinGetBinaryDataSize( void *pBuf )
{
	NNS_BINCNK_FILEHEADER	*pHeader;

	pHeader = (NNS_BINCNK_FILEHEADER *)pBuf;	// バイナリファイル情報ヘッダ
	SwapEndianCnkFileHader(pHeader);			// エディアン変換
	if( pHeader->Id != _SW32(NND_CHUNK_HEADER_DXG20) )
	{
		return 0;
	}

	return (Uint32)(pHeader->OfsNOF0 - pHeader->OfsData); 
}

/*----------------------------------------------------------------------------
    関数名 : smpTexSetFilePath
    機　能 : テクスチャファイルロードパス設定
    書　式 : void smpTexSetFilePath( const char *sPath )
    引　数 : path : テクスチャパス
    戻り値 : なし
    説　明 : テクスチャのカレントパスを設定します。
----------------------------------------------------------------------------*/
void smpTexSetFilePath( const char *sPath )
{
	strcpy( smpsTexturePath, (char *)sPath );
}

/*---------------------------------------------------------------------------
    関数名 : smpTexLoadFileOne
    機　能 : ファイルテクスチャのロード（1枚）
    書　式 : Sint32 smpLoadTextureFileOne(void *pTexInfo,NNS_TEXFILE *pFile)
    引　数 :  pTexInfo   : NNS_TEXINFO構造体のポインタ
              pFile      : NNS_TEXFILE構造体のポインタ
    戻り値 : 成功１　失敗ー１
    説　明 : テクスチャリストに設定されているテクスチャをロードします。
---------------------------------------------------------------------------*/
Sint32 smpTexLoadFileOne(NNS_TEXINFO *pTexInfo,NNS_TEXFILE *pTexFile)
{
	FILE		*fp;
	Uint8		*texbuf,*texbufroot;
	NVS_XVRHEADER	*pXvrObj;
	Uint16 MinFilter,MagFilter;
	Uint32 GlobalIndex;
	Uint32 Bank;
	Sint32 ret;
	char		filename[MAX_PATH];
	Sint32 size;

	if(!(pTexFile->fType & NND_TEXFTYPE_NO_FILENAME)){
/* ---------ファイルのロード スタート--------- */
		strcpy( (char *)filename, smpsTexturePath );
		strcat( (char *)filename, pTexFile->Filename );

		if( (fp = fopen( filename, "rb" ) ) == NULL )
			return -1;
		size = _filelength( _fileno( fp ) );
		texbufroot = texbuf = (Uint8 *)malloc( size );
		if( texbuf == NULL ){
			fclose( fp );
			return -1;
		}

		if( fread( texbuf, size, 1, fp ) != 1 ){
			free(texbuf);
			fclose( fp );
			return -1;
		}

		fclose( fp );
		
		//型が違うが無理やりコピーする
		pXvrObj = (NVS_XVRHEADER*)&(pTexInfo->xvrobj);
		memcpy(pXvrObj, texbuf, sizeof(NVS_XVRHEADER));
		// GBIXチャンクがあった場合XVRとする
		if(pXvrObj->gbix_cnk_long == 'XIBG'){
			if (pXvrObj->xbTexHeader.Dummy[0] == 0) {
				texbuf += 0x800;
			}
			else{
				texbuf += 0x40;
			}
		}
		else{
			//pTexInfo->xvrobj.attrが0以外のときはXVRとするので
			//Zeroクリアする
			memset(pXvrObj, 0, sizeof(NVS_XVRHEADER));
		}

/* ---------ファイルのロード　エンド--------- */

		if(pTexFile->fType & NND_TEXFTYPE_NO_FILTER){
			MinFilter = NND_MIN_NEAREST;
			MagFilter = NND_MAG_NEAREST;
		}
		else{
			MinFilter = pTexFile->MinFilter;
			MagFilter = pTexFile->MagFilter;
		}
		
		if(pTexFile->fType & NND_TEXFTYPE_LISTGLBIDX){
			//リストにあったのを使う
			GlobalIndex = pTexFile->GlobalIndex;
		}
		else{
			GlobalIndex = 0;
		}
		
		if(pTexFile->fType & NND_TEXFTYPE_LISTBANK){
			//リストにあったのを使う
			Bank = pTexFile->Bank;
		}
		else{
			Bank = 0;
		}

		//XVR以外の場合はsizeにテクスチャのサイズを入れる
		ret = nnLoadTextureMemoryOneDXG20(pTexInfo,
									texbuf,
									MinFilter,
									MagFilter,
									GlobalIndex,
									(Uint16)Bank,
									NND_TEXFLAG_ALLOCATE, size);
		free(texbufroot);
	}
	else{
		pTexInfo->GlobalIndex = pTexFile->GlobalIndex;
		pTexInfo->Bank = pTexFile->Bank;
		pTexInfo->Flag = 0;
		ret = 1;
	}


	return ret;
}

/*---------------------------------------------------------------------------
    関数名 : smpLoadTextureFile
    機　能 : ファイルテクスチャのロード
    書　式 : Sint32 smpTexLoadFile( NNS_TEXLIST *pTexList, NNS_TEXFILELIST *pFileList )
    引　数 : pTexList  : テクスチャリスト
             pFileList : テクスチャファイルリスト
    戻り値 : 成功１　失敗ー１
    説　明 : テクスチャリストに設定されているテクスチャをロードします。
---------------------------------------------------------------------------*/
Sint32 smpTexLoadFile( NNS_TEXLIST *pTexList, NNS_TEXFILELIST *pFileList )
{
	Sint32		i, ret;
	NNS_TEXINFO *pTexInfo;
	NNS_TEXFILE *pFile;
	
	pTexInfo = pTexList->pTexInfoList;
	pFile    = pFileList->pTexFileList;
	
	for( i = 0; i < pFileList->nTex; i++ )
	{
		ret = smpTexLoadFileOne( pTexInfo, pFile );
		if( ret < 0 )
			return ret;

		pTexInfo++;
		pFile++;
	}
	
	return 1;
}

/*---------------------------------------------------------------------------
    関数名 : smpTexRelease
    機　能 : テクスチャのリリース
    書　式 : Sint32 smpTexRelease(NNS_TEXLIST *pTexList)
    引　数 : pTexList   : テクスチャリストのポインタ
    戻り値 : 成功１　失敗ー１
    説　明 : テクスチャリストに設定されているテクスチャをリリースします。
---------------------------------------------------------------------------*/
Sint32 smpTexRelease(NNS_TEXLIST *pTexList)
{
	NNS_TEXINFO *pTexInfo;
	Sint32 i;
	Sint32 ret;
	
	pTexInfo = (NNS_TEXINFO *)pTexList->pTexInfoList;
	
	for(i = 0;i < pTexList->nTex;i++){
		if(pTexInfo->Flag & NND_TEXFLAG_ALLOCATE){
			/* テクスチャ領域開放 */
			ret = nnReleaseTextureOne(pTexInfo);
			if(ret < 0){
				return ret;
			}
		}
		pTexInfo++;
	}

	return 1;
}


/*----------------------------------------------------------------------------
    関数名 : smpClearVertexBufferInfoDXG20
    機　能 : 頂点バッファのクリア
    書　式 : void smpClearVertexBufferInfoDXG20( NNS_OBJECT *pObj )
    引　数 : pObj オブジェクト構造体のアドレス格納先
    戻り値 : なし
    説　明 : 頂点バッファ情報をクリアします
    備　考 : 
----------------------------------------------------------------------------*/
void smpClearVertexBufferInfoDXG20( NNS_OBJECT *pObj )
{
	Sint32 i;
	NNS_VTXLIST_DX_DESC			*pVtxDesc;
	
	for( i = 0; i < pObj->nVtxList; i++ ){
#if 0 /* 2008.05.13 */
		pVtxDesc = (NNS_VTXLIST_DX_DESC *)pObj->pVtxListPtrList[i].pVtxList;
#if ( NND_PLATFORM == NND_PLATFORM_XB )
		pVtxDesc->D3DVertexBuffer.Common = 0;
		pVtxDesc->D3DVertexBuffer.Data = 0;
		pVtxDesc->D3DVertexBuffer.Lock = 0;
#endif
#if ( NND_PLATFORM == NND_PLATFORM_DX8 || NND_PLATFORM == NND_PLATFORM_DX9 )
		pVtxDesc->pD3DVertexBuffer = NULL;
		pVtxDesc->pD3DVertexDecl = NULL;
		pVtxDesc->pD3DVertexMorphDecl = NULL;
#endif
#else
		if(pObj->pVtxListPtrList[i].fType & NND_VTXTYPE_DX_VERTEXDESC){
			pVtxDesc = (NNS_VTXLIST_DX_DESC *)pObj->pVtxListPtrList[i].pVtxList;
			pVtxDesc->pD3DVertexBuffer = NULL;
			pVtxDesc->pD3DVertexDecl = NULL;
			pVtxDesc->pD3DVertexMorphDecl = NULL;
		}
#endif
	}
}

/******************************************************************************/
/*----------------------------------------------------------------------------
    関数名 : smpMakeVertexShaderFileName
    機　能 : シェーダファイル名作成
    書　式 : void smpMakeVertexShaderFileName(const char *compiledshaderpath, char *fname, const NNS_STDSHADER_PROFILE *profile)
    引　数 : fname              : ファイル名
	         compiledshaderpath : コンパイル済みシェーダ出力／読み込みパス
    　　　   profile            : シェーダプロファイル
    戻り値 : なし
    説　明 : シェーダプロファイルごとにユニークなシェーダファイル名を作成します。
    備　考 : 
----------------------------------------------------------------------------*/
void smpMakeVertexShaderFileName(char *fname, const char *compiledshaderpath, const NNS_STDSHADER_PROFILE *profile)
{
	NNS_STDSHADER_NAME name = nnGetStdShaderName(profile);

	sprintf(fname, "%s/nnstdshader_%08x%08x%08x%08x.vsh",
		compiledshaderpath, (Uint32)(name.high >> 32), (Uint32)(name.high), (Uint32)(name.low >> 32), (Uint32)(name.low));
}

/*----------------------------------------------------------------------------
    関数名 : smpMakePixelShaderFileName
    機　能 : シェーダファイル名作成
    書　式 : smpMakePixelShaderFileName(char *fname, const NNS_STDSHADER_PROFILE *profile)
    引　数 : fname              : ファイル名
	         compiledshaderpath : コンパイル済みシェーダ出力／読み込みパス
    　　　   profile            : シェーダプロファイル
    戻り値 : なし
    説　明 : シェーダプロファイルごとにユニークなシェーダファイル名を作成します。
    備　考 : 
----------------------------------------------------------------------------*/
void smpMakePixelShaderFileName(char *fname, const char *compiledshaderpath, const NNS_STDSHADER_PROFILE *profile)
{
	NNS_STDSHADER_NAME name = nnGetStdShaderName(profile);

	sprintf(fname, "%s/nnstdshader_%08x%08x%08x%08x.psh",
		compiledshaderpath, (Uint32)(name.high >> 32), (Uint32)(name.high), (Uint32)(name.low >> 32), (Uint32)(name.low));
}

/*----------------------------------------------------------------------------
    関数名 : smpCompileStdShaderToWrite
    機　能 : シェーダをコンパイルしてファイルに出力する
    書　式 : static Sint32 smpCompileStdShaderToWrite(const char *pSrcData, Uint32 SrcDataLen, const NNE_STDSHADER_PROFILE shaderProfile, const NNS_STDSHADER_PROFILE *profile, char *compiledFilename)
    引　数 : pSrcData         : シェーダソース
	         SrcDataLen       : シェーダソースサイズ
			 shaderProfile    : NNE_STDSHADER_PROFILE_VERTEX or NNE_STDSHADER_PROFILE_PIXEL
			 profile          : シェーダプロファイル格納ポインタ
			 compiledFilename : ファイル名
    戻り値 : 
    説　明 : 
    備　考 : 
----------------------------------------------------------------------------*/
static Sint32 smpCompileStdShaderToWrite(const char *pSrcData, Uint32 SrcDataLen, const NNE_STDSHADER_PROFILE shaderProfile, const NNS_STDSHADER_PROFILE *profile, char *compiledFilename)
{
	LPD3DXBUFFER        pShader;
	LPD3DXCONSTANTTABLE pConstantTable;
	Sint32              result = 0;
	if(nnCompileStdShaderDXG20(pSrcData, SrcDataLen, shaderProfile, profile, &pShader, &pConstantTable) < 0){
		/* コンパイルエラー */
		return(-1);
	}
	/* 書き込み */
	{
		FILE *fp;
		fp = fopen(compiledFilename, "wb");
		if(fp != NULL){
			DWORD  size;
			LPVOID ptr;
			size = pShader->lpVtbl->GetBufferSize(pShader);
			ptr  = pShader->lpVtbl->GetBufferPointer(pShader);
			fwrite(ptr, size, 1, fp);
			fclose(fp);
		} else{
			result = -2;
			NNM_ASSERT(0, "Cannot write file name.\n");
		}
	}
	/* Release */
	if(pShader != NULL)        pShader->lpVtbl->Release(pShader);
	if(pConstantTable != NULL) pConstantTable->lpVtbl->Release(pConstantTable);
	return(result);
}

/*----------------------------------------------------------------------------
    関数名 : smpPreBuildStdShader
    機　能 : シェーダコンパイル＆ロード
    書　式 : Sint32 smpPreBuildStdShader( const char *vertexshader,  Uint32 vtxshadersize,
	                                      const char *fragmentshader, Uint32 fragshadersize,
										  const char *compiledshaderpath,
										  NNE_BOOL recompile )
    引　数 : vertexshader	    : 頂点シェーダソース
    　　　   vtxshadersize	    : 頂点シェーダソースサイズ
    　　　   fragmentshader	    : フラグメントシェーダソース
    　　　   fragshadersize	    : フラグメントシェーダソースサイズ
			 compiledshaderpath : コンパイル済みシェーダ出力／読み込みパス
	         recompile          : 上書きコンパイル
    戻り値 : 成功０　失敗ー１
    説　明 : シェーダをコンパイルします。
	　　　   既にコンパイル済みのシェーダファイルが存在すれば、コンパイルせずに読み込みます。（recompileがfalseのとき）
    備　考 : 先にnnRegistObjectStdShaderProfiles(),nnRegistPliableObjectStdShaderProfiles() などを使用して
	　　　   必要なシェーダプロファイルを登録しておくこと
----------------------------------------------------------------------------*/
Sint32 smpPreBuildStdShader( const char *vertexshader,  Uint32 vtxshadersize,
							 const char *fragmentshader, Uint32 fragshadersize,
							 const char *compiledshaderpath,
							 NNE_BOOL recompile )
{
	char compiledFilename[_MAX_PATH];

	#define SMP_DEFAULT_SHADER_BUFFER_SIZE	32768
	char     *pShaderBuffer = smpMemAlloc(SMP_DEFAULT_SHADER_BUFFER_SIZE);
	Sint32 ShaderBufferSize = SMP_DEFAULT_SHADER_BUFFER_SIZE;

	NNS_STDSHADER_PROFILE profile;

	MKDIR(compiledshaderpath);

	/* 未ビルドシェーダプロファイル取得 */
	while (nnGetUnbuildStdShaderProfileOne(&profile) > 0) {
		NNS_COMPILED_STDSHADER_PROFILE compiledShader;
		IDirect3DVertexShader9 *pVtxShader;
		IDirect3DPixelShader9  *pPixelShader;
		LPD3DXCONSTANTTABLE		pVtxConstTbl;
		LPD3DXCONSTANTTABLE		pPixelConstTbl;
		HRESULT hr;
		FILE   *fp;
		Sint32  filesize;

		/*----- 頂点シェーダ -----*/
		{
			smpMakeVertexShaderFileName(compiledFilename, compiledshaderpath, &profile);

			fp = recompile ? NULL : fopen(compiledFilename, "rb");

			if (!fp) {	// コンパイル済みシェーダファイルがなければコンパイルする
				if(smpCompileStdShaderToWrite(vertexshader, vtxshadersize, NNE_STDSHADER_PROFILE_VERTEX, &profile, compiledFilename) < 0){
					NNM_ASSERT(0, "Compile error : vertex shader");
					return -1;
				}
				fp = fopen(compiledFilename, "rb");
				NNM_ASSERT(fp, "Open file error : vertex shader");
				if (fp == NULL) return -1;
			}

			// コンパイル済みシェーダ読み込み
			fseek(fp, 0, SEEK_END);
			filesize = ftell(fp);
			fseek(fp, 0, SEEK_SET);

			if (ShaderBufferSize < filesize) {
				ShaderBufferSize = filesize;
				smpMemFree(pShaderBuffer);
				pShaderBuffer = smpMemAlloc(filesize);
			}

			fread(pShaderBuffer, 1, filesize, fp);
			fclose(fp);

			/**/
			hr = IDirect3DDevice9_CreateVertexShader(g_pd3dDevice, (DWORD*)pShaderBuffer, &pVtxShader);
			if( FAILED(hr) ){ 
				NNM_ASSERT(0,"Vertex Shader Creation Failed\n");
			}
			/**/
			D3DXGetShaderConstantTable( (DWORD*)pShaderBuffer, &pVtxConstTbl);
		}
		/*----- ピクセルシェーダ -----*/
		{
			smpMakePixelShaderFileName(compiledFilename, compiledshaderpath, &profile);

			fp = recompile ? NULL : fopen(compiledFilename, "rb");

			if (!fp) {	// コンパイル済みシェーダファイルがなければコンパイルする
				if(smpCompileStdShaderToWrite(fragmentshader, fragshadersize, NNE_STDSHADER_PROFILE_PIXEL, &profile, compiledFilename) < 0){
					NNM_ASSERT(0, "Compile error : pixel shader");
					return -1;
				}
				fp = fopen(compiledFilename, "rb");
				NNM_ASSERT(fp, "Open file error : pixel shader");
				if (fp == NULL) return -1;
			}

			// コンパイル済みシェーダ読み込み
			fseek(fp, 0, SEEK_END);
			filesize = ftell(fp);
			fseek(fp, 0, SEEK_SET);

			if (ShaderBufferSize < filesize) {
				ShaderBufferSize = filesize;
				smpMemFree(pShaderBuffer);
				pShaderBuffer = smpMemAlloc(filesize);
			}

			fread(pShaderBuffer, 1, filesize, fp);
			fclose(fp);

			/**/
			hr = IDirect3DDevice9_CreatePixelShader(g_pd3dDevice, (DWORD*)pShaderBuffer, &pPixelShader);
			if( FAILED(hr) ){ 
				NNM_ASSERT(0,"Pixel Shader Creation Failed\n");
			}
			/**/
			D3DXGetShaderConstantTable( (DWORD*)pShaderBuffer, &pPixelConstTbl);
		}
		/* シェーダをNNに登録 */
		{
			compiledShader.ShaderType     = NNE_STDSHADERTYPE_HLSL;
			compiledShader.pVertexShader  = pVtxShader;
			compiledShader.pPixelShader   = pPixelShader;
			compiledShader.pVtxConstTbl   = pVtxConstTbl;
			compiledShader.pPixelConstTbl = pPixelConstTbl;
			nnRegistCompiledStdShaderProfile(&compiledShader, &profile);
		}
	}

	smpMemFree(pShaderBuffer);

	return 0;
}

/*----------------------------------------------------------------------------
    関数名 : smpDeleteSpace
    機　能 : 空白を削除
    書　式 : static void smpDeleteSpace(char *dst, const char *src)
    引　数 : dst : 文字列
	         src : 文字列
    戻り値 : なし
    説　明 : 空白を削除します
    備　考 : 
----------------------------------------------------------------------------*/
static void smpDeleteSpace(char *dst, const char *src)
{
	/* 空白をスキップする */
	while(*src == ' ' || *src == '\t') src++;
	strcpy(dst, src);
	{
		Sint32 len;
		if((len=strlen(dst)) > 0){
			do{
				len--;
			} while(dst[len] == ' ' || dst[len] == '\t');
			dst[len+1] = '\0';
		}
	}
}

/*----------------------------------------------------------------------------
    関数名 : smpSetIncludePathDXG20
    機　能 : パスの設定
    書　式 : NNE_BOOL smpSetIncludePathDXG20(const char *pPath)
    引　数 : pPath : パス
    戻り値 : 登録 1 未登録 0 エラー-1
    説　明 : パスの設定をします。
    備　考 : パスを複数設定するときは句切り文字';'を使います。
----------------------------------------------------------------------------*/
Sint32 smpSetIncludePathDXG20(const char *pPath)
{
	Sint32 cnt;
	const char *ptr;
	if(pPath == NULL) return(0); /* 未登録 */
	{	/* パス数を求める */
		ptr = pPath;
		cnt = 0;
		while(*ptr != '\0'){
			if(*ptr == ';'){
				cnt++;
			}
			ptr++;
		}
		cnt++;
	}
	{	/* パスを格納するためのメモリを確保 */
		char **pPathList;
		NNE_BOOL result;
		Sint32 i, j;
		/* リストのメモリを確保 */
		pPathList = (char**)smpMemAlloc(sizeof(char**) * cnt);
		if(pPathList == NULL) return(-1); /* Error */
		/* パスのメモリを確保 */
		result = NNE_TRUE;
		for(i=0; i<cnt; i++){
			pPathList[i] = (char*)smpMemAlloc(sizeof(char) * MAX_PATH);
			if(pPathList[i] == NULL){result=NNE_FALSE; break;} /* Error */
		}
		if(result == NNE_FALSE){
			/* Error 処理 */
			for(j=0; j<i; j++){
				smpMemFree(pPathList[j]);
			}
			smpMemFree(pPathList);
			return(-1);
		}
		/* インクルードパスのメモリの解放 */
		smpIncludePathDispose();
		/**/
		g_pSmpPathList = pPathList;
		g_smpPathMax   = cnt;
	}
	{	/* パスを登録 */
		char   buf[1024], buf2[1024];
		Sint32 len;
		ptr = pPath;
		cnt = 0;
		len = 0;

		while(*ptr != '\0'){
			if(*ptr != ';'){
				buf[len++] = *ptr;
			} else{
				buf[len++] = '\0';
				/* 空白を削除 */
				smpDeleteSpace(buf2, buf);
				if(strlen(buf2) > 0){
					strcpy(g_pSmpPathList[g_smpPathNb++], buf2);
				}
				len = 0;
			}
			ptr++;
		}
		if(len > 0){
			buf[len++] = '\0';
			/* 空白を削除 */
			smpDeleteSpace(buf2, buf);
			if(strlen(buf2) > 0){
				strcpy(g_pSmpPathList[g_smpPathNb++], buf2);
			}
		}
	}
	if(g_smpPathNb == 0){
		/* インクルードパスのメモリの解放 */
		smpIncludePathDispose();
		return(0); /* 未登録 */
	}

#if 0 /* Debug */
	{
		Sint32 i;
		printf("max = %d\n", g_smpPathMax);
		for(i=0; i<g_smpPathNb; i++){
			printf("[%d] %s;\n", i, g_pSmpPathList[i]);
		}
	}
#endif
	return(1); /* 登録 */
}

/*----------------------------------------------------------------------------
    関数名 : smpIncludeCallbackDXG20
    機　能 : #include 擬似命令用のコールバック関数
    書　式 : long smpIncludeCallbackDXG20( unsigned int mode, unsigned int argc, const void *argv[])
    引　数 : mode   : コールバックのモード
	                  0 : Open モード
					  1 : Close モード
			 argc   : mode に対する引数の数
                      mode == 0 : argc = 5
					  mode == 1 : argc = 1
			 argv[] : mode に対する引数
                      mode == 0
					    argv[0] : D3DXINCLUDE_TYPE IncludeType  : [in] #include ファイルの位置。「D3DXINCLUDE_TYPE」を参照してください。
					    argv[1] : LPCSTR           pFileName    : [in] #include ファイルの名前。
					    argv[2] : LPCVOID          pParentData  : [in] #include ファイルをインクルードするコンテナへのポインタ。
					    argv[3] : LPCVOID         *ppData       : [out] インクルード擬似命令が格納された、返されるバッファへのポインタ。このポインタは、ID3DXInclude::Close が呼び出されるまで有効です。
					    argv[4] : UINT            *pBytes       : [out] ppData で返されるバイト数。
					  mode == 1 :
					    argv[0] : LPCVOID pData                 : [in] インクルード擬似命令が格納された、返されるバッファへのポインタ。対応する ID3DXInclude::Open 呼び出しによって返されたポインタ。
    戻り値 : 成功 S_OK 失敗 E_FAIL
    説　明 : #include 擬似命令用のコールバック関数です。
    備　考 : シェーダコンパイル時などに呼び出される。
----------------------------------------------------------------------------*/
long smpIncludeCallbackDXG20( unsigned int mode, unsigned int argc, const void *argv[])
{
	HRESULT result = E_FAIL;
	//
	switch(mode){
		case 0: /* Open */
			if(argc == 5){
				//D3DXINCLUDE_TYPE IncludeType  = *((D3DXINCLUDE_TYPE*)&argv[0]);
				LPCSTR           pFileName    = (LPCSTR)           argv[1];
				//LPCVOID          pParentData  = (LPCVOID)          argv[2];
				LPCVOID         *ppData       = (LPCVOID*)         argv[3];
				UINT            *pBytes       = (UINT*)            argv[4];
				{
					Uint32 codeSize;
					void  *pCodeBuf;
					char   buf[MAX_PATH];
					Sint32 i;
					/* (1)パスにあればパスからファイルを読み込む　*/
					for(i=0; i<g_smpPathNb; i++){
						sprintf(buf, "%s/%s", g_pSmpPathList[i], pFileName );
						/* ファイルサイズを取得 */
						codeSize = smpGetFileSize( buf );
						if(codeSize > 0){
							/* メモリの確保 */
							pCodeBuf = smpMemAlloc( codeSize );
							/* ファイルを読み込みます */
							smpReadFile( buf, pCodeBuf );
							result = S_OK;
							break;
						}
					}
					/* (2)パスになければ pFileName の場所から読み込む */
					if(result != S_OK){
						sprintf(buf, "%s", pFileName );
						/* ファイルサイズを取得 */
						codeSize = smpGetFileSize( buf );
						if(codeSize > 0){
							/* メモリの確保 */
							pCodeBuf = smpMemAlloc( codeSize );
							/* ファイルを読み込みます */
							smpReadFile( buf, pCodeBuf );
							result = S_OK;
						}
					}
					if(result == S_OK){
						*pBytes = codeSize;
						*ppData = pCodeBuf;
					}
				}
			}
			break;

		case 1: /* Close */
			if(argc == 1){
				LPCVOID pData = (LPCVOID)argv[0];
				if(pData != NULL){
					void  *pCodeBuf = (void*) pData;
					/* メモリを解放 */
					smpMemFree( pCodeBuf );
					result = S_OK;
				}
			}
			break;

		default:
			break;
	}
	return(result);
}

/*----------------------------------------------------------------------------
    関数名 : smpOutputCompileShaderErrorDXG20
    機　能 : シェーダコンパイルエラーをファイルに出力する
    書　式 : void smpOutputCompileShaderErrorDXG20(Uint32 shaderProfile, const void *buf, Uint32 bufSize)
    引　数 : shaderProfile : シェーダプロファイル
	                         0 : 頂点シェーダ
	                         1 : ピクセルシェーダ
	         buf           : エラーメッセージのバッファ
			 bufSize       : バッファのサイズ
    戻り値 : なし
    説　明 : シェーダコンパイルエラーをファイルに出力します
    備　考 : 
----------------------------------------------------------------------------*/
void smpOutputCompileShaderErrorDXG20(Uint32 shaderProfile, const void *buf, Uint32 bufSize)
{
	FILE *fp;
	UNREFERENCED_PARAMETER(bufSize);
	fp = fopen( "error.log", "wb" );
	if ( fp ) {
		if(shaderProfile == 0){
			fprintf( fp, "Compile error in vertex shader.\n" );
		} else if(shaderProfile == 1){
			fprintf( fp, "Compile error in pixel shader.\n" );
		}
		fprintf( fp, "%s", buf);
		fclose( fp );
	}
}


/* End of file */
