// programmer :
ANDY
//
website : http://tw.myblog.yahoo.com/mmogc3d-mmogc3d/
// last
date : 2009.06.03
#include "AV_AniScript.h"
#include "AV_MemoryPool.h"
#include "AV_Other.h"
#include "AV_Utility.h"
#include "AV_IndexTable.hpp"
#include "AV_Encode.hpp"
#include "AV_CSDebug.h"
#include <wchar.h>
AniScriptEventInterface *gInterfaceLink;
//=============================================================================================================================================================
struct InfoNode
{
WCHAR *Str;
long Value;
};
static InfoNode gAntiErrorNode = { L"NO", 0 };
struct ColumnInfo : AV_MemoryPoolStruct< InfoNode >
{
inline InfoNode* Get( DWORD index )
{
if( index < ObjectMax )
return &pBuffer[ index ];
return &gAntiErrorNode; // here returns a parameter of non-NULL;
}
};
//=============================================================================================================================================================
WCHAR *gAniCommandTable[ ANI_COMMAND_MAX ] =
{
L"NULL",
L"CREATE_ANI",
L"CREATE_RECT",
L"CTRL_ANI_START",
L"CTRL_ANI_END",
L"SET_ANI_RANGE",
L"PLAY_ANI_RANGE",
L"PLAY_ANI",
L"CONTINUE_PLAY_ANI",
L"WAIT_ANI",
L"WAIT_ALL_ANI",
L"WAIT",
L"BREAK",
L"PLAY_SOUND",
L"SET_ANI",
L"SET_IMAGE",
L"SET_POS",
L"SET_DELAY",
L"SET_COLOR",
L"SET_R",
L"SET_G",
L"SET_B",
L"SET_A",
L"SET_PIC_INDEX",
L"SET_COUNT",
L"SET_LAYER",
L"SHOW_PIC",
L"ADD_X",
L"ADD_Y",
L"FADE_IN",
L"FADE_OUT",
L"CALL_FUNC",
L"CALL_SCRIPT",
L"END_ANI",
L"END",
};
DWORD gAniCommandValueTable[ ANI_COMMAND_MAX ];
struct AniNode
{
DWORD Number;
DWORD ImageIndex;
DWORD PicIndex, PicMax, BackupPicIndex;
long X, Y;
BYTE R, G, B;
long A, AMax, Aadd;
DWORD WaitFrameCount;
DWORD WaitFrameMax;
long RunCount;
BOOL PlayFlag;
BOOL PlayEndFlag;
BOOL UseRectFlag;
POINT RectSize;
BOOL InsertCommandFlag;
AV_MemoryPoolPointerArray< ColumnInfo > InsertCommandTable;
};
#define ANI_UNLIMITED_COUNT (-1)
#define ANI_LAYER_MAX 4
#define ANI_NODE_MAX 32
struct AniNodeManager : AV_MemoryPool2HeadArrayList< AniNode, ANI_NODE_MAX >
{
DWORD Number;
};
#define COMMAND_INDEX_MAX 100
#define PARAMETER_MAX 10
struct AniLayerManager
{
//------------------------------------------------------------
AV_MemoryPool2HeadArrayList< AniNodeManager, ANI_LAYER_MAX > LayerTable;
static IndexTableClass sIndexCommandTable;
AV_MemoryPoolArrayStruct< long, PARAMETER_MAX > ParameterTable;
AniNode *pActNodeLink;
AniNodeManager *pActLayerLink;
DWORD RunCommandYIndex;
long WaitFrameCount;
BOOL PlayEndFlag;
//------------------------------------------------------------
void Create()
{
Reset();
DWORD i = 0;
LayerTable.Create();
for( i = 0; i < ANI_LAYER_MAX; ++i )
{
AniNodeManager *manager = LayerTable.GetNode();
manager->Create();
manager->Number = i;
LayerTable.Link( manager );
}
if( !sIndexCommandTable.IndexTable.pBuffer )
{
sIndexCommandTable.Create( COMMAND_INDEX_MAX, 100 );
for( i = 1; i < ANI_COMMAND_MAX; ++i )
{
gAniCommandValueTable[ i ] = i;
sIndexCommandTable.AddStrW( gAniCommandTable[ i ], &gAniCommandValueTable[ i ] );
}
}
ParameterTable.Create();
}
void Release()
{
MPNode2< AniNode > *node = NULL, *del_node = NULL;
MPNode2< AniNodeManager > *manager = LayerTable.pHeadNode;
while( manager )
{
node = manager->pHeadNode;
while( node )
{
del_node = node;
node = node->pNext;
del_node->InsertCommandTable.Clear();
manager->Unlink( del_node );
manager->ReleaseNode( del_node );
}
manager = manager->pNext;
}
Reset();
}
//------------------------------------------------------------
void Reset()
{
pActNodeLink = NULL;
pActLayerLink = NULL;
RunCommandYIndex = 0;
WaitFrameCount = 0;
PlayEndFlag = FALSE;
}
//------------------------------------------------------------
BOOL CheckCommandValue()
{
DWORD value_table[ ANI_COMMAND_MAX ] = { 0 };
DWORD str_length = 0, add_value = 0, n = 0, i = 0;
WCHAR *command = NULL;
for( n = 1; n < ANI_COMMAND_MAX; ++n )
{
add_value = 0;
str_length = (DWORD)wcslen( gAniCommandTable[ n ] );
command = gAniCommandTable[ n ];
for( i = 0; i < str_length; ++i )
{
add_value += command[ i ];
}
value_table[ n ] = add_value;
}
DWORD cmp_value = 0;
for( n = 1; n < ANI_COMMAND_MAX; ++n )
{
cmp_value = value_table[ n ];
for( i = n + 1; i < ANI_COMMAND_MAX; ++i )
{
if( cmp_value == value_table[ i ] )
return FALSE; // failed
}
}
return TRUE;
}
//------------------------------------------------------------
MPNode2< AniNode >* GetActNode( DWORD number )
{
MPNode2< AniNode > *mp_node = pActLayerLink->pHeadNode;
while( mp_node )
{
if( mp_node->Number == number )
{
return mp_node;
}
mp_node = mp_node->pNext;
}
return NULL;
}
long GetValue( InfoNode *node )
{
if( node->Str[0] == L'P' )
{
DWORD length = (DWORD)wcslen( node->Str );
WCHAR value_buff[ 4 ] = { 0 };
if( length >= 4 )
return node->Value; // for ignore the error.
for( DWORD i = 1; i < length; ++i )
{
value_buff[ i - 1 ] = node->Str[ i ];
}
long *parameter_index = ParameterTable.Get( _wtoi( value_buff ) );
if( parameter_index )
return *parameter_index;
return 0;
}
return node->Value;
}
//------------------------------------------------------------
BOOL RunScript( struct ReadyPlayInfo *script );
BOOL PlayAni( struct ReadyPlayInfo *script );
//------------------------------------------------------------
};
IndexTableClass AniLayerManager::sIndexCommandTable;
//#############################################################################################################################################################
//=============================================================================================================================================================
struct ScriptInfo
{
DWORD Number;
AV_MemoryPoolCtrlStruct< DWORD > CommandValueTable;
AV_MemoryPoolPointerArray< ColumnInfo > StringTable;
BOOL LoadFlag;
};
struct ReadyPlayInfo
{
ScriptInfo *pScriptLink;
DWORD ManageNumber;
AniLayerManager AniManager;
BOOL LoadFlag;
BOOL PlayFlag;
class AniScriptManager *pParentLink;
void Release()
{
PlayFlag = FALSE;
AniManager.Release();
}
};
#define LAYER_READY_NODE_MAX 100
struct ReadyScriptLayerNode : AV_MemoryPool2HeadArrayList< ReadyPlayInfo, LAYER_READY_NODE_MAX >
{
};
#define READY_SCRIPT_LAYER_MAX 3
class AniScriptManager : public AniScriptComponent
{
public :
//------------------------------------------------------------
DWORD TableCountYMax;
AV_MemoryPoolStruct< WCHAR > Buffer;
DWORD BufferStartIndex;
AV_MemoryPoolStruct< WCHAR > TempSymbolBuffer;
DWORD TempSymbolBufferUseIndex;
DWORD StartYLineIndex;
AV_MemoryPoolStruct< WCHAR* > TempPointerBuffer;
DWORD TempFileSize;
//------------------------------------------------------------
AV_MemoryPoolStruct< ScriptInfo > ScriptTable;
AV_MemoryPool2HeadList< ReadyScriptLayerNode > PlayScriptLayerList;
//------------------------------------------------------------
void *pUserInfo;
BOOL AniDisplayFlag;
//------------------------------------------------------------
AniScriptManager( DWORD ani_script_max, DWORD table_y_max, DWORD temp_pointer_buffer_max, DWORD buffer_bytes_max );
~AniScriptManager();
//------------------------------------------------------------
ReadyScriptLayerNode* SearchReadyScriptLayerNode( DWORD layer_index );
ReadyPlayInfo* SearchReadyPlayNode( DWORD layer_index, DWORD manage_number );
void Run( ScriptInfo *script, DWORD column_y );
//------------------------------------------------------------
public :
//------------------------------------------------------------
virtual void vRelease();
//------------------------------------------------------------
virtual BOOL vLoadScriptFile( WCHAR *path_file_name, DWORD script_index, BOOL decode_flag );
//------------------------------------------------------------
virtual BOOL vRunScript( DWORD script_index, DWORD manage_number, DWORD layer_index );
virtual BOOL vPlayAni();
virtual BOOL vPlayToEndScript( DWORD manage_number, DWORD layer_index );
virtual BOOL vStopScript( DWORD manage_number, DWORD layer_index );
virtual BOOL vSetParameter( DWORD manage_number, DWORD parameter_index, long parameter_value, DWORD layer_index );
virtual BOOL vCheckScriptPlaying( DWORD manage_number, DWORD layer_index );
virtual void vSetAniDisplayFlag( BOOL flag ){ AniDisplayFlag = flag; }
//------------------------------------------------------------
};
//=============================================================================================================================================================
AniScriptComponent* AniScriptComponent::sCreate( AniScriptEventInterface *this_link, void *user_info, DWORD ani_script_max, DWORD table_y_max, DWORD temp_pointer_buffer_max, DWORD buffer_bytes_max )
{
gInterfaceLink = this_link;
AniScriptManager *obj = NULL;
AVATAR_NEW( obj, AniScriptManager( ani_script_max, table_y_max, temp_pointer_buffer_max, buffer_bytes_max ) );
obj->pUserInfo = user_info;
return obj;
}
//=============================================================================================================================================================
void AniScriptManager::vRelease()
{
AniScriptManager *_this = this;
AVATAR_DELETE( _this );
}
//=============================================================================================================================================================
#define CHAR_BUFFER_MAX 2048
AniScriptManager::AniScriptManager( DWORD ani_script_max, DWORD table_y_max, DWORD temp_pointer_buffer_max, DWORD buffer_bytes_max )
{
TableCountYMax = table_y_max;
TempSymbolBuffer.Create( CHAR_BUFFER_MAX );
TempPointerBuffer.Create( temp_pointer_buffer_max );
Buffer.Create( buffer_bytes_max );
BufferStartIndex = 0;
TempSymbolBufferUseIndex = 0;
StartYLineIndex = 0;
TempFileSize = 0;
ScriptInfo *script = NULL;
ScriptTable.Create( ani_script_max );
AniDisplayFlag = TRUE;
#if 0 // first check only.
if( !ScriptTable.pBuffer[ 0 ].AniManager.CheckCommandValue() )
{
Debug::WBox( "AniScriptManager::AniScriptManager error : some of values of ani command are equal." );
::Beep( 1000, 150 );
}
#endif
PlayScriptLayerList.Create( READY_SCRIPT_LAYER_MAX );
for( DWORD i = 0; i < READY_SCRIPT_LAYER_MAX; ++i )
{
PlayScriptLayerList.Link( PlayScriptLayerList.GetNode() );
}
MPNode2< ReadyScriptLayerNode > *ready_layer_node = PlayScriptLayerList.pHeadNode;
while( ready_layer_node )
{
ready_layer_node->Create();
ready_layer_node = ready_layer_node->pNext;
}
}
//=============================================================================================================================================================
AniScriptManager::~AniScriptManager()
{
// just explain, I have release memories. (actually, they do not need to be released.)
MPNode2< ReadyScriptLayerNode > *ready_layer_node = PlayScriptLayerList.pHeadNode;
while( ready_layer_node )
{
PlayScriptLayerList.Unlink( ready_layer_node );
PlayScriptLayerList.ReleaseNode( ready_layer_node );
}
}
//=============================================================================================================================================================
ReadyScriptLayerNode* AniScriptManager::SearchReadyScriptLayerNode( DWORD layer_index )
{
DWORD search_layer_index = 0;
MPNode2< ReadyScriptLayerNode > *ready_layer_node = PlayScriptLayerList.pHeadNode;
while( ready_layer_node )
{
if( search_layer_index == layer_index )
return ready_layer_node;
++search_layer_index;
ready_layer_node = ready_layer_node->pNext;
}
return NULL;
}
//=============================================================================================================================================================
ReadyPlayInfo* AniScriptManager::SearchReadyPlayNode( DWORD layer_index, DWORD manage_number )
{
ReadyScriptLayerNode *ready_layer_node = SearchReadyScriptLayerNode( layer_index );
if( !ready_layer_node )
return NULL;
MPNode2< ReadyPlayInfo > *ready_node = ready_layer_node->pHeadNode;
while( ready_node )
{
if( ready_node->ManageNumber == manage_number )
return ready_node;
ready_node = ready_node->pNext;
}
return NULL;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vSetParameter( DWORD manage_number, DWORD parameter_index, long parameter_value, DWORD layer_index )
{
ReadyPlayInfo *ready_node = SearchReadyPlayNode( layer_index, manage_number );
if( !ready_node )
return FALSE;
long *parameter = ready_node->AniManager.ParameterTable.Get( parameter_index );
if( !parameter )
return FALSE;
*parameter = parameter_value;
return TRUE;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vCheckScriptPlaying( DWORD manage_number, DWORD layer_index )
{
ReadyPlayInfo *ready_node = SearchReadyPlayNode( layer_index, manage_number );
if( !ready_node )
return FALSE;
return ready_node->PlayFlag;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vRunScript( DWORD script_index, DWORD manage_number, DWORD layer_index )
{
ScriptInfo *script = ScriptTable.Get( script_index );
if( !script )
return FALSE;
ReadyScriptLayerNode *ready_layer_node = SearchReadyScriptLayerNode( layer_index );
if( !ready_layer_node )
return FALSE;
ReadyPlayInfo *ready_node = SearchReadyPlayNode( layer_index, manage_number );
if( ready_node )
{
ready_node->AniManager.Reset();
if( ready_node->PlayFlag )
return TRUE;
return FALSE;
}
ready_node = ready_layer_node->GetNode();
ready_node->ManageNumber = manage_number;
ready_node->AniManager.Create();
ready_node->pScriptLink = script;
ready_node->PlayFlag = TRUE;
ready_node->pParentLink = this;
ready_layer_node->Link( ready_node );
return TRUE;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vPlayToEndScript( DWORD manage_number, DWORD layer_index )
{
ReadyPlayInfo *ready_node = SearchReadyPlayNode( layer_index, manage_number );
if( !ready_node )
return FALSE;
if( !ready_node->PlayFlag )
return FALSE;
ready_node->AniManager.PlayEndFlag = TRUE;
return TRUE;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vStopScript( DWORD manage_number, DWORD layer_index )
{
ReadyScriptLayerNode *ready_layer_node = SearchReadyScriptLayerNode( layer_index );
if( !ready_layer_node )
return FALSE;
MPNode2< ReadyPlayInfo > *ready_node = ready_layer_node->pHeadNode, *del_node = NULL;
while( ready_node )
{
if( ready_node->ManageNumber == manage_number )
{
gInterfaceLink->vOnScriptEnd( ready_node->pParentLink->pUserInfo,
ready_node->pScriptLink->Number,
ready_node->ManageNumber );
ready_node->Release();
del_node = ready_node;
ready_layer_node->Unlink( del_node );
ready_layer_node->ReleaseNode( del_node );
break;
}
ready_node = ready_node->pNext;
}
return TRUE;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vPlayAni()
{
BOOL script_run_flag = FALSE;
MPNode2< ReadyPlayInfo > *ready_node = NULL, *del_node = NULL;
MPNode2< ReadyScriptLayerNode > *ready_layer_node = PlayScriptLayerList.pHeadNode;
while( ready_layer_node )
{
ready_node = ready_layer_node->pHeadNode, del_node = NULL;
while( ready_node )
{
script_run_flag = ready_node->AniManager.RunScript( ready_node );
ready_node->AniManager.PlayAni( ready_node );
if( !script_run_flag )
{
gInterfaceLink->vOnScriptEnd(
ready_node->pParentLink->pUserInfo,
ready_node->ManageNumber, ready_node->pScriptLink->Number );
ready_node->Release();
del_node = ready_node;
ready_node = ready_node->pNext;
ready_layer_node->Unlink( del_node );
ready_layer_node->ReleaseNode( del_node );
continue;
}
ready_node = ready_node->pNext;
}
ready_layer_node = ready_layer_node->pNext;
}
return TRUE;
}
//=============================================================================================================================================================
BOOL AniScriptManager::vLoadScriptFile( WCHAR *path_file_name, DWORD script_index, BOOL decode_flag )
{
ScriptInfo *script = ScriptTable.Get( script_index );
if( !script )
return FALSE;
if( script->LoadFlag == TRUE )
return TRUE;
script->CommandValueTable.Create( TableCountYMax );
script->StringTable.Create( TableCountYMax );
DWORD file_size = 0;
BOOL flag = FALSE;
WCHAR encode_path_file_name[ 256 ];
if( decode_flag )
{
file_size = Buffer.GetFileSize( path_file_name );
if( file_size > Buffer.BufferSize )
{
Debug::WBox( "AniScriptManager::vLoadScriptFile error : the size of buffer is not enough. (%s) if( file_size(%d) > Buffer.BufferSize(%d) )", path_file_name, file_size, Buffer.BufferSize );
return FALSE;
}
flag = Buffer.Load( path_file_name );
FILE_ENCODE_0( FILE_ENCODE_STATIC_CODE, Buffer.pBuffer, file_size );
}
else
{
size_t length = wcslen( path_file_name );
wcscpy_s( encode_path_file_name, 256, path_file_name );
if( encode_path_file_name[ length - 3 ] == 'e' &&
encode_path_file_name[ length - 2 ] == 'n' &&
encode_path_file_name[ length - 1 ] == 'c' )
encode_path_file_name[ length - 4 ] = 0; // delete .enc
file_size = Buffer.GetFileSize( encode_path_file_name );
if( file_size > Buffer.BufferSize )
{
Debug::WBox( "AniScriptManager::vLoadScriptFile error : the size of buffer is not enough. (%s) if( file_size(%d) > Buffer.BufferSize(%d) )", encode_path_file_name, file_size, Buffer.BufferSize );
return FALSE;
}
flag = Buffer.Load( encode_path_file_name );
}
if( !flag )
return flag;
BufferStartIndex = 0;
TempSymbolBufferUseIndex = 0;
StartYLineIndex = 0;
TempFileSize = file_size;
WCHAR *p = &Buffer.pBuffer[ BufferStartIndex ];
if( *p == 65279 ) // 65279 is a first symbol for unicode file.
{
++BufferStartIndex;
++p;
}
Run( script, 99999999 );
script->Number = script_index;
script->LoadFlag = TRUE;
return flag;
}
//=============================================================================================================================================================
void AniScriptManager::Run( ScriptInfo *script, DWORD column_y )
{
WCHAR *p = &Buffer.pBuffer[ BufferStartIndex ];
DWORD count = BufferStartIndex;
const DWORD buff_max = TempFileSize / 2;
WCHAR c = 0;
DWORD column_x = 0;
ColumnInfo *column = NULL;
DWORD i = 0;
DWORD str_length = 0, add_value = 0;
const static WCHAR end1_key = '\r'; // 13
const static WCHAR end2_key = '\n'; // 10
const static WCHAR space_key = 32;
const static WCHAR tab_key = 9;
const static WCHAR explain_key = ';';
const static WCHAR separate_key = ',';
while( 1 )
{
// first get symbol
while( 1 )
{
if( count++ >= buff_max )
{
BufferStartIndex = buff_max;
return;
}
c = *p++;
if( c == space_key || c == tab_key )
{
}
else if( c == explain_key )
{
BOOL break_flag = FALSE;
while( 1 )
{
if( count++ >= buff_max )
{
break_flag = TRUE;
break;
}
c = *p++;
if( c == end1_key )
{
if( count++ >= buff_max )
{
break_flag = TRUE;
break;
}
c = *p++;
if( c == end2_key )
break; // break this line
}
}
if( break_flag )
break;
continue;
}
else if( c == end1_key )
{
if( count++ >= buff_max )
break;
c = *p++; // end2_key
}
else
{
TempSymbolBuffer.pBuffer[ TempSymbolBufferUseIndex++ ] = c;
break;
}
}
//----------------------------------------------------
// get column text
while( 1 )
{
if( count++ >= buff_max ) // to end...
break;
c = *p++;
if( c == space_key || c == tab_key || c == separate_key || c == end1_key || count == buff_max )
{
if( TempSymbolBufferUseIndex == 0 )
continue;
if( count == buff_max )
{
TempSymbolBuffer.pBuffer[ TempSymbolBufferUseIndex ] = c;
++TempSymbolBufferUseIndex;
}
TempSymbolBuffer.pBuffer[ TempSymbolBufferUseIndex ] = 0;
//---------------------
WCHAR *str = (WCHAR*)AV_KernelMemoryPool::sMemoryAllocate( (TempSymbolBufferUseIndex + 1) * sizeof(WCHAR) );
wmemcpy( str, TempSymbolBuffer.pBuffer, TempSymbolBufferUseIndex );
str[ TempSymbolBufferUseIndex ] = 0;
//---------------------
if( column_x < TempPointerBuffer.ObjectMax )
TempPointerBuffer.pBuffer[ column_x ] = str;
else
{
Debug::WBox( L"AniScriptManager::Run error : StartYLineIndex= %d, parameter_count(%d) > pointer_buffer_count(%d), newstr= %s", StartYLineIndex, column_x, TempPointerBuffer.ObjectMax, str );
}
TempSymbolBufferUseIndex = 0;
++column_x;
//-------------------------------------------
if( count == buff_max )
break;
if( c == end1_key )
{
if( count++ >= buff_max )
break;
c = *p++;
if( c == end2_key )
break; // break this line
}
}
else if( c == explain_key )
{
// here jumps those symbols of junk, like explain.
while( 1 )
{
if( count++ >= buff_max ) // to end...
break;
c = *p++;
if( c != end1_key )
{
}
else
{
if( count++ >= buff_max ) // to end...
break;
c = *p++;
if( c == end2_key )
break; // break this line
}
}
break;
}
else
{
TempSymbolBuffer.pBuffer[ TempSymbolBufferUseIndex ] = c;
++TempSymbolBufferUseIndex;
}
}
if( script->StringTable.UseCount < TableCountYMax )
{
++script->StringTable.UseCount;
column = (ColumnInfo*)AV_KernelMemoryPool::sMemoryAllocate( sizeof( ColumnInfo ) );
script->StringTable.pBuffer[ StartYLineIndex ] = column;
column->Create( column_x );
for( i = 0; i < column_x; i++ )
{
column->pBuffer[ i ].Str = TempPointerBuffer.pBuffer[ i ];
column->pBuffer[ i ].Value = _wtoi( TempPointerBuffer.pBuffer[ i ] );
}
//---------
add_value = 0;
str_length = (DWORD)wcslen( column->pBuffer[ 0 ].Str );
for( i = 0; i < str_length; i++ )
{
add_value += column->pBuffer[ 0 ].Str[ i ];
}
script->CommandValueTable.pBuffer[ script->StringTable.UseCount - 1 ] = add_value;
}
else
{
Debug::WBox( L"AniScriptManager::Run error : script->StringTable.UseCount(%d) >= TableCountYMax(%d)", script->StringTable.UseCount, TableCountYMax );
return;
}
if( column_y == StartYLineIndex )
{
BufferStartIndex = count;
++StartYLineIndex;
return;
}
column_x = 0;
++StartYLineIndex;
}
}
//#############################################################################################################################################################
//=============================================================================================================================================================
BOOL AniLayerManager::PlayAni( ReadyPlayInfo *ready_node )
{
MPNode2< AniNode > *node = NULL, *del_node = NULL;
MPNode2< AniNodeManager > *manager = LayerTable.pHeadNode;
while( manager )
{
node = manager->pHeadNode;
while( node )
{
if( !node->PlayFlag )
{
node = node->pNext;
continue;
}
if( ready_node->pParentLink->AniDisplayFlag )
{
if( node->UseRectFlag )
{
RECT rect;
rect.left = node->X;
rect.top = node->Y;
rect.right = rect.left + node->RectSize.x;
rect.bottom = rect.top + node->RectSize.y;
gInterfaceLink->vOnScriptColorRect(
&rect,
node->R,
node->G,
node->B,
(BYTE)node->A );
}
else
{
gInterfaceLink->vOnScriptAniUpdate( ready_node->pParentLink->pUserInfo,
ready_node->pScriptLink->Number,
ready_node->ManageNumber,
node->Number,
node->PicIndex );
gInterfaceLink->vOnScriptDraw( node->ImageIndex,
node->X,
node->Y,
node->PicIndex,
NULL,
A_RENDER_STATE__COLOR_KEY,
node->R,
node->G,
node->B,
(BYTE)node->A );
}
if( node->Aadd )
node->A = (node->A += node->Aadd) > node->AMax ? node->AMax : node->A;
}
if( !node->PlayEndFlag &&
++node->WaitFrameCount >= node->WaitFrameMax + ClockInfo::sGetANIWhileFrames() )
{
node->WaitFrameCount = 0;
if( ++node->PicIndex > node->PicMax )
{
--node->PicIndex;
}
}
// if( node->InsertCommandFlag ) // retain
// {
// }
node = node->pNext;
}
manager = manager->pNext;
}
if( LayerTable.LinkNodeCount == 0 )
return FALSE;
return TRUE;
}
//=============================================================================================================================================================
BOOL AniLayerManager::RunScript( ReadyPlayInfo *ready_node )
{
DWORD command = 0, command_max = ready_node->pScriptLink->StringTable.UseCount;
ITNode *index_node =NULL;
AniNode *node = NULL;
MPNode2< AniNode > *act_node = NULL;
AniNodeManager *manager = (AniNodeManager*)LayerTable.pHeadNode;
ColumnInfo *column = NULL;
pActLayerLink = manager;
for( ; RunCommandYIndex < command_max; RunCommandYIndex++ )
{
column = ready_node->pScriptLink->StringTable.pBuffer[ RunCommandYIndex ];
index_node = sIndexCommandTable.SearchValueByValue( ready_node->pScriptLink->CommandValueTable.pBuffer[ RunCommandYIndex ] );
if( !index_node )
continue; // failed
command = *((DWORD*)index_node->pDataLink);
switch( command )
{
case ANI_COMMAND__CREATE_ANI :
{
pActNodeLink = node = pActLayerLink->GetNode();
pActLayerLink->Link( node );
node->Number = GetValue( column->Get( 1 ) );
node->ImageIndex = GetValue( column->Get( 2 ) );
node->X = GetValue( column->Get( 3 ) );
node->Y = GetValue( column->Get( 4 ) );
node->WaitFrameMax = GetValue( column->Get( 5 ) );
node->R = 255;
node->G = 255;
node->B = 255;
node->A = 255;
node->Aadd = GetValue( column->Get( 6 ) );
node->AMax = 255;
node->RunCount = 1;
if( node->Aadd )
node->A = 0;
break;
}
case ANI_COMMAND__CREATE_RECT :
{
pActNodeLink = node = pActLayerLink->GetNode();
pActLayerLink->Link( node );
node->Number = GetValue( column->Get( 1 ) );
node->X = GetValue( column->Get( 2 ) );
node->Y = GetValue( column->Get( 3 ) );
node->RectSize.x = GetValue( column->Get( 4 ) );
node->RectSize.y = GetValue( column->Get( 5 ) );
node->R = (BYTE)GetValue( column->Get( 6 ) );
node->G = (BYTE)GetValue( column->Get( 7 ) );
node->B = (BYTE)GetValue( column->Get( 8 ) );
node->A = node->AMax = GetValue( column->Get( 9 ) );
node->Aadd = GetValue( column->Get( 10 ) );
node->UseRectFlag = TRUE;
node->RunCount = 1;
node->PlayFlag = TRUE;
if( node->Aadd )
node->A = 0;
break;
}
case ANI_COMMAND__CTRL_ANI_START :
{
break;
}
case ANI_COMMAND__CTRL_ANI_END :
{
break;
}
case ANI_COMMAND__SET_ANI_RANGE :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
act_node->PicIndex = GetValue( column->Get( 2 ) );
act_node->PicMax = GetValue( column->Get( 3 ) );
act_node->PlayFlag = TRUE;
act_node->BackupPicIndex = act_node->PicIndex;
break;
}
case ANI_COMMAND__PLAY_ANI_RANGE :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
act_node->PicIndex = GetValue( column->Get( 2 ) );
act_node->PicMax = GetValue( column->Get( 3 ) );
act_node->PlayFlag = TRUE;
act_node->BackupPicIndex = act_node->PicIndex;
++RunCommandYIndex; // to play
return TRUE;
}
case ANI_COMMAND__PLAY_ANI :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
act_node->PicIndex = 0;
act_node->PicMax = gInterfaceLink->vOnScriptGetImageCount( node->ImageIndex );
act_node->PlayFlag = TRUE;
act_node->BackupPicIndex = act_node->PicIndex;
++RunCommandYIndex; // to play
return TRUE;
}
case ANI_COMMAND__CONTINUE_PLAY_ANI :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
// act_node->PicIndex = 0; // no clear, continue to use same PicIndex.
act_node->PicMax = gInterfaceLink->vOnScriptGetImageCount( node->ImageIndex );
act_node->PlayFlag = TRUE;
act_node->BackupPicIndex = act_node->PicIndex;
++RunCommandYIndex; // to play
return TRUE;
}
case ANI_COMMAND__WAIT_ANI :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
if( PlayEndFlag )
break;
if( act_node->PicIndex >= act_node->PicMax )
{
if( act_node->RunCount <= ANI_UNLIMITED_COUNT ||
--act_node->RunCount > 0 )
{
act_node->PicIndex = act_node->BackupPicIndex;
}
else
break;
}
return TRUE;
}
case ANI_COMMAND__WAIT_ALL_ANI :
{
DWORD end_count = 0;
act_node = pActLayerLink->pHeadNode;
while( act_node )
{
if( !act_node->PlayFlag || act_node->PlayEndFlag )
{
act_node = act_node->pNext;
++end_count;
continue;
}
if( act_node->PicIndex >= act_node->PicMax )
{
if( act_node->RunCount <= ANI_UNLIMITED_COUNT )
{
act_node->PicIndex = act_node->BackupPicIndex;
}
else
{
if( --act_node->RunCount > 0 )
{
act_node->PicIndex = act_node->BackupPicIndex;
}
else
{
if( act_node->PicMax > 0 )
act_node->PicIndex = act_node->PicMax - 1;
else
act_node->PicIndex = 0;
act_node->PlayEndFlag = TRUE;
++end_count;
}
}
}
act_node = act_node->pNext;
}
if( end_count == pActLayerLink->LinkNodeCount )
break;
return TRUE;
}
case ANI_COMMAND__WAIT :
{
if( PlayEndFlag )
break;
if( ++WaitFrameCount >= GetValue( column->Get( 1 ) ) + ClockInfo::sGetANIWhileFrames() )
{
WaitFrameCount = 0;
break;
}
return TRUE;
}
case ANI_COMMAND__BREAK :
{
++RunCommandYIndex;
return TRUE;
}
case ANI_COMMAND__PLAY_SOUND :
{
gInterfaceLink->vOnScriptPlaySound( ready_node->pParentLink->pUserInfo,
GetValue( column->Get( 1 ) ) );
break;
}
case ANI_COMMAND__SET_ANI :
{
pActNodeLink = GetActNode( GetValue( column->Get( 1 ) ) );
break;
}
case ANI_COMMAND__SET_IMAGE :
{
if( pActNodeLink )
pActNodeLink->ImageIndex = GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_POS :
{
if( pActNodeLink )
{
pActNodeLink->X = GetValue( column->Get( 1 ) );
pActNodeLink->Y = GetValue( column->Get( 2 ) );
}
break;
}
case ANI_COMMAND__SET_DELAY :
{
if( pActNodeLink )
pActNodeLink->WaitFrameMax = GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_COLOR :
{
if( pActNodeLink )
{
pActNodeLink->R = (BYTE)GetValue( column->Get( 1 ) );
pActNodeLink->G = (BYTE)GetValue( column->Get( 2 ) );
pActNodeLink->B = (BYTE)GetValue( column->Get( 3 ) );
pActNodeLink->A = (BYTE)GetValue( column->Get( 4 ) );
}
break;
}
case ANI_COMMAND__SET_R :
{
if( pActNodeLink )
pActNodeLink->R = (BYTE)GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_G :
{
if( pActNodeLink )
pActNodeLink->G = (BYTE)GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_B :
{
if( pActNodeLink )
pActNodeLink->B = (BYTE)GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_A :
{
if( pActNodeLink )
{
pActNodeLink->A = (BYTE)GetValue( column->Get( 1 ) );
pActNodeLink->Aadd = (BYTE)GetValue( column->Get( 2 ) );
InfoNode *node = column->Get( 3 );
if( ::wcscmp( node->Str, gAntiErrorNode.Str ) != 0 )
pActNodeLink->AMax = (BYTE)GetValue( column->Get( 3 ) );
}
break;
}
case ANI_COMMAND__SET_PIC_INDEX :
{
if( pActNodeLink )
pActNodeLink->PicIndex = (BYTE)GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_COUNT :
{
if( pActNodeLink )
pActNodeLink->RunCount = GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__SET_LAYER :
{
break;
}
case ANI_COMMAND__SHOW_PIC :
{
if( pActNodeLink )
{
pActNodeLink->PicIndex = GetValue( column->Get( 1 ) );
pActNodeLink->BackupPicIndex = pActNodeLink->PicIndex;
pActNodeLink->PlayFlag = TRUE;
}
break;
}
case ANI_COMMAND__ADD_X :
{
if( pActNodeLink )
pActNodeLink->X += GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__ADD_Y :
{
if( pActNodeLink )
pActNodeLink->Y += GetValue( column->Get( 1 ) );
break;
}
case ANI_COMMAND__FADE_IN :
{
DWORD alpha_sub = GetValue( column->Get( 1 ) );
act_node = pActLayerLink->pHeadNode;
BOOL fade_in_running_flag = FALSE;
while( act_node )
{
if( act_node->A < act_node->AMax )
{
act_node->A += alpha_sub;
if( act_node->A > act_node->AMax )
act_node->A = act_node->AMax;
fade_in_running_flag = TRUE;
}
act_node = act_node->pNext;
}
if( fade_in_running_flag )
return TRUE;
break;
}
case ANI_COMMAND__FADE_OUT :
{
DWORD alpha_sub = GetValue( column->Get( 1 ) );
act_node = pActLayerLink->pHeadNode;
BOOL fade_out_running_flag = FALSE;
act_node->Aadd = 0;
while( act_node )
{
if( act_node->A > 0 )
{
act_node->A -= alpha_sub;
if( act_node->A < 0 )
act_node->A = 0;
fade_out_running_flag = TRUE;
}
act_node = act_node->pNext;
}
if( fade_out_running_flag )
return TRUE;
break;
}
case ANI_COMMAND__CALL_FUNC :
{
gInterfaceLink->vOnScriptExtraFunc( ready_node->pParentLink->pUserInfo,
ready_node->pScriptLink->Number,
ready_node->ManageNumber, GetValue( column->Get( 1 ) ) );
break;
}
case ANI_COMMAND__CALL_SCRIPT :
{
break;
}
case ANI_COMMAND__END_ANI :
{
if( !(act_node = GetActNode( GetValue( column->Get( 1 ) ) )) )
break;
gInterfaceLink->vOnScriptAniEnd( ready_node->pParentLink->pUserInfo,
ready_node->pScriptLink->Number,
ready_node->ManageNumber, act_node->Number );
pActLayerLink->Unlink( act_node );
pActLayerLink->ReleaseNode( act_node );
break;
}
case ANI_COMMAND__END :
{
return FALSE;
}
}
}
return FALSE; // end script
}
// eof