#include "AnimationEditor_EventEdit.h" #include "AnimationEditor_AnimSelect.h" #include "AnimationEditor.h" #include "AnimationEditor_AnimSelect.h" #include "ToolLib.h" #include // イベントマップ表示の基準座標 #define MAP_X (32) #define MAP_Y (SCREEN_HEIGHT - 126) // イベントマップ表示の横幅 #define MAP_WIDTH (SCREEN_WIDTH - 80) // イベントマップ表示の両端の縦線の高さ #define MAP_VLINE_HEIGHT (8) // イベントマップ表示のイベントがある位置の縦線の高さ #define MAP_EVENT_VLINE_HEIGHT (16) // イベントマップ表示の再生時間の位置を表す縦線の高さ #define MAP_PLAYTIMELINE_HEIGHT (32) // アニメーションの総時間を表示する座標 #define TOTAL_TIME_X (32) #define TOTAL_TIME_Y (SCREEN_HEIGHT - 106) // 「戻る」ボタンの位置 #define BACK_BUTTON_X (0) #define BACK_BUTTON_Y (4 + TOPSPACE + g_EEData.TopSpace.SpaceStart) // 「戻る」ボタンを表示する範囲の高さ #define BACK_BUTTON_H (30) // イベントリストの座標と幅と高さ #define LIST_X (4) #define LIST_Y (0) #define LIST_W (256) #define LIST_H (128) // イベント編集処理のボタンの基準座標 #define BUTTONS_X (0) #define BUTTONS_Y (4 +TOOL_SCROLLBAR_WIDTH+g_EEData.ButtonSpace.SpaceStart) // イベント編集処理のボタンを配置する範囲の高さ #define BUTTONS_H (136) // イベントタイプリストの座標と幅と高さ #define TYPELIST_X (4) #define TYPELIST_Y (0) #define TYPELIST_W (256) #define TYPELIST_H (80) // 物理サウンドリストの座標と幅と高さ #define PHYSICSSOUND_LIST_X (4) #define PHYSICSSOUND_LIST_Y (0) #define PHYSICSSOUND_LIST_W (256) #define PHYSICSSOUND_LIST_H (50) // アニメーションキャンセルを有効にするかどうかを選択する為のリストの座標と幅と高さ #define NEXTANIMENABLE_LIST_X (SCREEN_WIDTH - ( NEXTANIMENABLE_LIST_W + 24 ) ) #define NEXTANIMENABLE_LIST_Y (152 + TOOL_WINDOW_NAME_HEIGHT) #define NEXTANIMENABLE_LIST_W (256) #define NEXTANIMENABLE_LIST_H (36) // アニメキャンセル後に再生するアニメのリストの座標と幅と高さ #define NEXTANIM_LIST_X (SCREEN_WIDTH - ( NEXTANIM_LIST_W + 24 ) ) #define NEXTANIM_LIST_Y (NEXTANIMENABLE_LIST_Y + NEXTANIMENABLE_LIST_H + TOOL_WINDOW_NAME_HEIGHT + 8) #define NEXTANIM_LIST_W (256) #define NEXTANIM_LIST_H (320) // イベントの時間を操作する際の入力リピート開始までの時間 #define TIME_BUTTON_REPEAT (0.2f) // イベントの時間を操作する際の入力リピートが開始した状態での再リピートまでの時間 #define TIME_BUTTON_LOOP_REPEAT (0.05f) // イベント編集処理情報 typedef struct _SEventEditData { // 表示状態情報ハンドル int TVisible; // スペース管理情報ハンドル int TSpaceManage; // 説明文を表示するためのスペース情報 SToolSpace TopSpace; // 「戻る」ボタンのハンドル int BackTButton; // イベントリスト表示用ウインドウのハンドル int ListTWindow; // イベントリストのハンドル int TList; // 操作ボタン部分用のスペース情報 SToolSpace ButtonSpace; // イベント追加ボタンのハンドル int AddTButton; // イベント削除ボタンのハンドル int DelTButton; // アニメーション再生ボタンのハンドル int AnimPlayTButton; // イベントの数が0の際に表示を消す処理用の表示状態情報のハンドル int ZeroTVisible; // イベントの時間を操作するボタンのハンドル int TimePlusTButton; int TimeMinusTButton; // 攻撃番号を操作するボタンのハンドル int AttackNoPlusTButton; int AttackNoMinusTButton; // 攻撃判定の起点となる3Dモデル中のフレームの番号を操作するボタンのハンドル int AttackPosPlusTButton; int AttackPosMinusTButton; // イベントタイプリスト表示用のウインドウのハンドル int TypeListTWindow; // イベントタイプリストのハンドル int TypeTList; // 物理サウンドリストとイベントタイプリストとの隙間用のスペース情報 SToolSpace PhysicsSoundListWindowSpace; // 物理サウンドリスト表示用のウインドウのハンドル int PhysicsSoundListTWindow; // 物理サウンドリストのハンドル int PhysicsSoundTList; // アニメキャンセルをするかどうかを選択するためのリスト表示用のウインドウのハンドル int NextAnimEnableTWindow; // アニメキャンセルをするかどうかを選択するためのリストのハンドル int NextAnimEnableTList; // アニメキャンセル後に再生するアニメのリスト表示用のウインドウのハンドル int NextAnimListTWindow; // アニメキャンセル後に再生するアニメのリストのハンドル int NextAnimListTList; // イベントの時間を加算するボタンが押されているかどうか bool TimePlusButtonBottom; // イベントの時間を加算するボタンのリピート処理に使用する時間計測用の変数 float TimePlusButtonBottomTime; // イベントの時間を減算するボタンが押されているかどうか bool TimeMinusButtonBottom; // イベントの時間を減算するボタンのリピート処理に使用する時間計測用の変数 float TimeMinusButtonBottomTime; } SEventEditData; // 各イベントタイプ別の線の色 int g_EventLineColorTable[ EAnimEventType_Num ][ 3 ] = { { 255, 255, 0 }, // EAnimEventType_Sound { 255, 255, 0 }, // EAnimEventType_PhysicsSound { 0, 255, 0 }, // EAnimEventType_AnimCancel { 0, 255, 255 }, // EAnimEventType_AttackStart { 255, 0, 255 }, // EAnimEventType_AttackEnd { 200, 200, 200 }, // EAnimEventType_Other }; SEventEditData g_EEData; // str1 の中から str2 の文字列が最後に登場するアドレスを取得する // 戻り値 : str1 の中から見つかった str2 の最後のアドレス // ( 見つからなかった場合は NULL が返る ) static char *_strrstr( // 検索対象の文字列 char *str1, // str1 の中から検索する文字列 char *str2 ); // イベントを時間順にソートする static void SortEvent( void ); // str1 の中から str2 の文字列が最後に登場するアドレスを取得する // 戻り値 : str1 の中から見つかった str2 の最後のアドレス // ( 見つからなかった場合は NULL が返る ) static char *_strrstr( // 検索対象の文字列 char *str1, // str1 の中から検索する文字列 char *str2 ) { char *p1; char *p2; // 最初の一致アドレスを取得する p2 = strstr( str1, str2 ); // 一つも一致する箇所が無かったらここで終了 if( p2 == NULL ) { return NULL; } for(;;) { // 次の一致箇所を取得する p1 = strstr( p2 + 1, str2 ); // 無かったらループを抜ける if( p1 == NULL ) { break; } // あったらアドレスを保存する p2 = p1; } // 最後に見つけた一致箇所のアドレスを返す return p2; } // イベントを時間順にソートする static void SortEvent( void ) { SCharaBaseInfo *CBInfo; SAnimInfo *AInfo; SAnimEventInfo TempEventInfo; int i; int j; CBInfo = CharaBase_GetInfo( g_AEData.TargetChara ); AInfo = &CBInfo->AnimInfo[ g_AEData.TargetAnim ].Info; // イベントを時間順にバブルソートする for( i = 0; i < AInfo->EventNum; i++ ) { for( j = i + 1; j < AInfo->EventNum; j++ ) { if( AInfo->Event[ i ].TimeI > AInfo->Event[ j ].TimeI ) { TempEventInfo = AInfo->Event[ i ]; AInfo->Event[ i ] = AInfo->Event[ j ]; AInfo->Event[ j ] = TempEventInfo; if( j == g_AEData.TargetEvent ) { g_AEData.TargetEvent = i; } else if( i == g_AEData.TargetEvent ) { g_AEData.TargetEvent = j; } } } } } // イベント編集処理の初期化を行う // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool EventEdit_Initialize( void ) { int i; // スペース管理情報の作成 g_EEData.TSpaceManage = ToolSpaceManage_Create( SCREEN_HEIGHT ); if( g_EEData.TSpaceManage == NULL ) { return false; } // 説明文を表示するスペース用のスペース情報を追加 if( !ToolSpaceManage_AddSpace( g_EEData.TSpaceManage, &g_EEData.TopSpace, TOPSPACE + BACK_BUTTON_H, true ) ) { return false; } // 「戻る」ボタンの作成 g_EEData.BackTButton = ToolButton_Create( false, "戻る", BACK_BUTTON_X + 4, BACK_BUTTON_Y, 50, BUTTON_H ); if( g_EEData.BackTButton == NULL ) { return false; } // イベントリスト表示用ウインドウの作成 g_EEData.ListTWindow = ToolWindow_Create( g_EEData.TSpaceManage, false, true, false, "イベント一覧", LIST_X, LIST_Y, LIST_W, LIST_H, LIST_W, LIST_H ); if( g_EEData.ListTWindow == NULL ) { return false; } // イベントリストの作成 g_EEData.TList = ToolList_Create(); if( g_EEData.TList == NULL ) { return false; } // イベントリストを初期化 ToolList_Initialize( g_EEData.TList, g_EEData.ListTWindow ); // 操作ボタン部分用のスペース情報を追加 if( !ToolSpaceManage_AddSpace( g_EEData.TSpaceManage, &g_EEData.ButtonSpace, BUTTONS_H, true ) ) { return false; } // イベント追加ボタンの作成 g_EEData.AddTButton = ToolButton_Create( false, "イベント追加", BUTTONS_X + 4, BUTTONS_Y + 0, 60, BUTTON_H ); if( g_EEData.AddTButton == NULL ) { return false; } // イベント削除ボタンの作成 g_EEData.DelTButton = ToolButton_Create( false, "イベント削除", BUTTONS_X + 64, BUTTONS_Y + 0, 60, BUTTON_H ); if( g_EEData.DelTButton == NULL ) { return false; } // アニメーション再生ボタンの作成 g_EEData.AnimPlayTButton = ToolButton_Create( false, "アニメ再生", BUTTONS_X + 4, BUTTONS_Y + 24, 60, BUTTON_H ); if( g_EEData.AnimPlayTButton == NULL ) { return false; } // イベントの数が0の際に表示を消す処理用の表示状態情報の作成 g_EEData.ZeroTVisible = ToolVisible_Create(); if( g_EEData.ZeroTVisible == NULL ) { return false; } // イベントの時間を操作するボタンの作成 g_EEData.TimePlusTButton = ToolButton_Create( false, "時間+", BUTTONS_X + 64, BUTTONS_Y + 48, 60, BUTTON_H ); if( g_EEData.TimePlusTButton == NULL ) { return false; } g_EEData.TimeMinusTButton = ToolButton_Create( false, "時間-", BUTTONS_X + 4, BUTTONS_Y + 48, 60, BUTTON_H ); if( g_EEData.TimeMinusTButton == NULL ) { return false; } // 攻撃番号を操作するボタンの作成 g_EEData.AttackNoPlusTButton = ToolButton_Create( false, "攻撃番号+", BUTTONS_X + 64, BUTTONS_Y + 72, 60, BUTTON_H ); if( g_EEData.AttackNoPlusTButton == NULL ) { return false; } g_EEData.AttackNoMinusTButton = ToolButton_Create( false, "攻撃番号-", BUTTONS_X + 4, BUTTONS_Y + 72, 60, BUTTON_H ); if( g_EEData.AttackNoMinusTButton == NULL ) { return false; } // 攻撃判定の起点となる3Dモデル中のフレームの番号を操作するボタンの作成 g_EEData.AttackPosPlusTButton = ToolButton_Create( false, "攻撃座標+", BUTTONS_X + 64, BUTTONS_Y + 92, 60, BUTTON_H ); if( g_EEData.AttackPosPlusTButton == NULL ) { return false; } g_EEData.AttackPosMinusTButton = ToolButton_Create( false, "攻撃座標-", BUTTONS_X + 4, BUTTONS_Y + 92, 60, BUTTON_H ); if( g_EEData.AttackPosMinusTButton == NULL ) { return false; } // イベントタイプリスト表示用のウインドウの作成 g_EEData.TypeListTWindow = ToolWindow_Create( g_EEData.TSpaceManage, false, true, false, "イベントタイプ一覧", TYPELIST_X, TYPELIST_Y, TYPELIST_W, TYPELIST_H, TYPELIST_W, TYPELIST_H ); if( g_EEData.TypeListTWindow == NULL ) { return false; } // イベントタイプリストの作成 g_EEData.TypeTList = ToolList_Create(); if( g_EEData.TypeTList == NULL ) { return false; } // イベントタイプリストの初期化 ToolList_Initialize( g_EEData.TypeTList, g_EEData.TypeListTWindow ); // 全てのイベントタイプをリストに追加 for( i = 0; i < EAnimEventType_Num; i++ ) { if( !ToolList_AddObj( g_EEData.TypeTList, GetAnimEventTypeName( ( EAnimEventType )i ) ) ) { return false; } } // 物理サウンドリストとイベントタイプリストとの隙間用のスペース情報を追加 if( !ToolSpaceManage_AddSpace( g_EEData.TSpaceManage, &g_EEData.PhysicsSoundListWindowSpace, 4, true ) ) { return false; } // 物理サウンドリスト表示用のウインドウの作成 g_EEData.PhysicsSoundListTWindow = ToolWindow_Create( g_EEData.TSpaceManage, false, true, false, "物理サウンド一覧", PHYSICSSOUND_LIST_X, PHYSICSSOUND_LIST_Y, PHYSICSSOUND_LIST_W, PHYSICSSOUND_LIST_H, PHYSICSSOUND_LIST_W, PHYSICSSOUND_LIST_H ); if( g_EEData.PhysicsSoundListTWindow == NULL ) { return false; } // 物理サウンドリストの作成 g_EEData.PhysicsSoundTList = ToolList_Create(); if( g_EEData.PhysicsSoundTList == NULL ) { return false; } // 物理サウンドリストの初期化 ToolList_Initialize( g_EEData.PhysicsSoundTList, g_EEData.PhysicsSoundListTWindow ); // 全ての物理サウンドリストに追加 for( i = 0; i < EAnimPhysicsSound_Num; i++ ) { if( !ToolList_AddObj( g_EEData.PhysicsSoundTList, GetAnimPhysicsSoundName( (EAnimPhysicsSound)i ))) { return false; } } // 表示状態情報の作成 g_EEData.TVisible = ToolVisible_Create(); if( g_EEData.TVisible == NULL ) { return false; } // アニメキャンセルをするかどうかを選択するためのリスト表示用のウインドウの作成 g_EEData.NextAnimEnableTWindow = ToolWindow_Create( -1, false, true, false, "アニメキャンセル有効設定", NEXTANIMENABLE_LIST_X, NEXTANIMENABLE_LIST_Y, NEXTANIMENABLE_LIST_W, NEXTANIMENABLE_LIST_H, NEXTANIMENABLE_LIST_W, NEXTANIMENABLE_LIST_H ); if( g_EEData.NextAnimEnableTWindow == NULL ) { return false; } // アニメキャンセルをするかどうかを選択するためのリストの作成 g_EEData.NextAnimEnableTList = ToolList_Create(); if( g_EEData.NextAnimEnableTList == NULL ) { return false; } // アニメキャンセルをするかどうかを選択するためのリストの初期化 ToolList_Initialize( g_EEData.NextAnimEnableTList, g_EEData.NextAnimEnableTWindow ); // アニメキャンセルをするかどうかの選択肢をリストに追加 if( !ToolList_AddObj( g_EEData.NextAnimEnableTList, "無効" ) ) { return false; } if( !ToolList_AddObj( g_EEData.NextAnimEnableTList, "有効" ) ) { return false; } // 初期状態では「無効」にしておく ToolList_SetSelectIndex( g_EEData.NextAnimEnableTList, 0 ); // アニメキャンセル後に再生するアニメのリスト表示用のウインドウの作成 g_EEData.NextAnimListTWindow = ToolWindow_Create( -1, false, true, false, "アニメキャンセル時再生アニメ一覧", NEXTANIM_LIST_X, NEXTANIM_LIST_Y, NEXTANIM_LIST_W, NEXTANIM_LIST_H, NEXTANIM_LIST_W, NEXTANIM_LIST_H ); if( g_EEData.NextAnimListTWindow == NULL ) { return false; } // アニメキャンセル後に再生するアニメのリストの作成 g_EEData.NextAnimListTList = ToolList_Create(); if( g_EEData.NextAnimListTList == NULL ) { return false; } // アニメキャンセル後に再生するアニメのリストの初期化 ToolList_Initialize( g_EEData.NextAnimListTList, g_EEData.NextAnimListTWindow ); // イベント編集処理で使用するウインドウやボタンと表示状態情報ハンドルを関連付ける ToolButton_SetVisibleHandle( g_EEData.BackTButton, g_EEData.TVisible ); ToolWindow_SetVisibleHandle( g_EEData.ListTWindow, g_EEData.TVisible ); ToolButton_SetVisibleHandle( g_EEData.AddTButton, g_EEData.TVisible ); ToolButton_SetVisibleHandle( g_EEData.DelTButton, g_EEData.TVisible ); ToolButton_SetVisibleHandle( g_EEData.AnimPlayTButton, g_EEData.TVisible ); ToolWindow_SetVisibleHandle( g_EEData.NextAnimEnableTWindow, g_EEData.TVisible ); ToolWindow_SetVisibleHandle( g_EEData.NextAnimListTWindow, g_EEData.TVisible ); ToolVisible_SetParent( g_EEData.ZeroTVisible, g_EEData.TVisible ); // イベントの数が0の際に表示を消す表示物を専用の表示状態情報ハンドルを関連付ける ToolButton_SetVisibleHandle( g_EEData.TimePlusTButton, g_EEData.ZeroTVisible ); ToolButton_SetVisibleHandle( g_EEData.TimeMinusTButton, g_EEData.ZeroTVisible ); ToolButton_SetVisibleHandle( g_EEData.AttackNoPlusTButton, g_EEData.ZeroTVisible ); ToolButton_SetVisibleHandle( g_EEData.AttackNoMinusTButton, g_EEData.ZeroTVisible ); ToolButton_SetVisibleHandle( g_EEData.AttackPosPlusTButton, g_EEData.ZeroTVisible ); ToolButton_SetVisibleHandle( g_EEData.AttackPosMinusTButton, g_EEData.ZeroTVisible ); ToolWindow_SetVisibleHandle( g_EEData.TypeListTWindow, g_EEData.ZeroTVisible ); ToolWindow_SetVisibleHandle( g_EEData.PhysicsSoundListTWindow,g_EEData.ZeroTVisible); // 正常終了 return true; } // イベント編集処理のイベントリストをセットアップする // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool EventEdit_SetupList( void ) { int i; SCharaBaseInfo *CBInfo; SAnimInfo *AInfo; SAnimEventInfo *AEInfo; // イベントリストを表示状態にする ToolVisible_SetVisible( g_EEData.TVisible, true ); // イベントリストを初期化する ToolList_Initialize( g_EEData.TList, g_EEData.ListTWindow ); CBInfo = CharaBase_GetInfo( g_AEData.TargetChara ); AInfo = &CBInfo->AnimInfo[ g_AEData.TargetAnim ].Info; // 対象のアニメーションのイベントを全てリストに追加する AEInfo = AInfo->Event; for( i = 0; i < AInfo->EventNum; i++, AEInfo++ ) { // イベントタイプによって分岐 switch( AEInfo->Type ) { case EAnimEventType_Sound: ToolList_AddObj( g_EEData.TList, "Frame:%.2f Sound[ %s ]", AEInfo->TimeF , AEInfo->SoundPath ); break; case EAnimEventType_PhysicsSound: ToolList_AddObj( g_EEData.TList, "Frame:%.2f PhysicsSound[ %s ]", AEInfo->TimeF, GetAnimPhysicsSoundName( AEInfo->PhysicsSound ) ); break; case EAnimEventType_AnimCancel: ToolList_AddObj( g_EEData.TList, "Frame:%.2f AnimCancel", AEInfo->TimeF ); break; case EAnimEventType_AttackStart: ToolList_AddObj(g_EEData.TList,"Frame:%.2f AttackStart No:%d PosIndex:%d", AEInfo->TimeF, AEInfo->AttackNo, AEInfo->AttackPosIndex ); break; case EAnimEventType_AttackEnd: ToolList_AddObj( g_EEData.TList, "Frame:%.2f AttackEnd No:%d", AEInfo->TimeF, AEInfo->AttackNo ); break; case EAnimEventType_Other: ToolList_AddObj( g_EEData.TList, "Frame:%.2f Other", AEInfo->TimeF ); break; } } // イベントの数が0ではないかどうかで処理を分岐 if( AInfo->EventNum > 0 ) { // イベントの数が0の際に表示を消す処理用の表示状態情報の状態を「表示」にする ToolVisible_SetVisible( g_EEData.ZeroTVisible, true ); // 編集対象のイベントの行を選択状態にする ToolList_SetSelectIndex( g_EEData.TList, g_AEData.TargetEvent ); AEInfo = &AInfo->Event[ g_AEData.TargetEvent ]; // イベントのタイプや物理サウンドタイプをリストに反映する ToolList_SetSelectIndex( g_EEData.TypeTList, AEInfo->Type ); ToolList_SetSelectIndex( g_EEData.PhysicsSoundTList, AEInfo->PhysicsSound ); // イベントが「攻撃判定開始」か「攻撃判定終了」の場合は攻撃番号編集用の // ボタンを表示状態にする if( AEInfo->Type == EAnimEventType_AttackStart || AEInfo->Type == EAnimEventType_AttackEnd ) { ToolButton_SetVisible( g_EEData.AttackNoPlusTButton, true ); ToolButton_SetVisible( g_EEData.AttackNoMinusTButton, true ); } else { ToolButton_SetVisible( g_EEData.AttackNoPlusTButton, false ); ToolButton_SetVisible( g_EEData.AttackNoMinusTButton, false ); } // イベントが「攻撃判定開始」の場合は攻撃起点のフレーム番号編集用の // ボタンを表示状態にする if( AEInfo->Type == EAnimEventType_AttackStart ) { ToolButton_SetVisible( g_EEData.AttackPosPlusTButton, true ); ToolButton_SetVisible( g_EEData.AttackPosMinusTButton, true ); } else { ToolButton_SetVisible( g_EEData.AttackPosPlusTButton, false ); ToolButton_SetVisible( g_EEData.AttackPosMinusTButton, false ); } // イベントタイプが物理サウンドだった場合は物理サウンド選択用ウインドウを表示する ToolWindow_SetVisible( g_EEData.PhysicsSoundListTWindow, AEInfo->Type == EAnimEventType_PhysicsSound ); } else { // イベントの数が0の際に表示を消す処理用の表示状態情報の状態を「非表示」にする ToolVisible_SetVisible( g_EEData.ZeroTVisible, false ); } // 正常終了 return true; } // イベント編集処理の状態推移処理を行う // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool EventEdit_Step( // 推移させる時間( 単位:秒 ) float StepTime ) { SAnimInfo *AInfo; SAnimEventInfo *AEInfo; SCharaBaseInfo *CBInfo; SCharaAnimBaseInfo *CABInfo; float TotalTime; bool Flag; char *String; char *CutString; char FilePathBuffer[ MAX_PATH ]; char SoundPathBuffer[ MAX_PATH ]; CBInfo = CharaBase_GetInfo( g_AEData.TargetChara ); CABInfo = &CBInfo->AnimInfo[ g_AEData.TargetAnim ]; AInfo = &CABInfo->Info; AEInfo = &AInfo->Event[ g_AEData.TargetEvent ]; TotalTime = MV1GetAnimTotalTime( CABInfo->Handle, 0 ); // 「戻る」ボタンが押されたらアニメーション選択に戻る if( ToolButton_GetClick( g_EEData.BackTButton, true ) ) { // キャラ選択・アニメーション選択・イベント編集の表示をOFFにする MainUIHide(); // アニメーション選択モードに変更する g_AEData.Mode = EEditMode_AnimSelect; // 選択イベントを初期化 g_AEData.TargetEvent = 0; // アニメーションキャンセルをするかどうかの情報を初期化 g_AEData.NextAnimValid = false; ToolList_SetSelectIndex( g_EEData.NextAnimEnableTList, 0 ); // メインウインドウへのファイルのドラック&ドロップを無効にする SetDragFileValidFlag( FALSE ); // アニメーション選択処理のアニメーションリストをセットアップする if( !AnimSelect_SetupList() ) { return false; } // 正常終了 return true; } // イベントタイプがサウンド再生で、 // 且つドラッグ&ドロップされたファイルがある場合は処理をする if( AEInfo->Type == EAnimEventType_Sound && GetDragFileNum() > 0 ) { // ファイルのパスを取得 GetDragFilePath( FilePathBuffer ); // ゲームのデータフォルダ下かどうかを調べるためにデータフォルダ名の一部が // ドロップされたファイルのパスに含まれるかをチェック String = strstr( FilePathBuffer, ANIM_SE_FILE_DIRECTORY_PATH ); // イベントサウンドは末尾に必ず _00.wav などの数値表示になっている必要が // あるので、それがあるかどうかを調べるために _00.wav がファイルパスに // 含まれるかどうかをチェック CutString = _strrstr( FilePathBuffer, "_00.wav" ); // 二つの文字列がどちらもファイルパスに含まれる場合はイベントサウンドで // 再生するファイルとして記憶する if( String != NULL && CutString != NULL ) { // ファイル名の先頭アドレスに移動 String += strlen( ANIM_SE_FILE_DIRECTORY_PATH ); // _00.wav などの部分を抜いたファイル名を保存 *CutString = '\0'; strcpy( AEInfo->SoundPath, String ); // サウンド処理にドロップされたサウンドファイルを追加する strcpy( SoundPathBuffer, "SE\\" ); strcat( SoundPathBuffer, String ); AEInfo->SoundHandle = Sound_AddSound( SoundPathBuffer, true ); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } } // イベントリストの状態が変化した場合は選択イベントを変更する if( ToolList_GetChange( g_EEData.TList, true ) ) { g_AEData.TargetEvent = ToolList_GetSelectIndex( g_EEData.TList ); // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // アニメーション再生ボタンが押されたらアニメーションを再生する if( ToolButton_GetClick( g_EEData.AnimPlayTButton, true ) ) { // 既に再生していたら停止する if( g_AEData.AnimPlay ) { // アニメーションの再生を停止する AnimStop(); // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); } else { // アニメーションの再生を開始する AnimPlay(); } } // イベントが一つでもあるかどうかで処理を分岐する if( AInfo->EventNum > 0 ) { // イベントタイプリストの状態が変化した場合はイベントのタイプを変更する if( ToolList_GetChange( g_EEData.TypeTList, true ) ) { AEInfo->Type = (EAnimEventType )ToolList_GetSelectIndex(g_EEData.TypeTList); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // 物理サウンドリストの状態が変化した場合はイベントの物理サウンドを変更する if( ToolList_GetChange( g_EEData.PhysicsSoundTList, true ) ) { AEInfo->PhysicsSound = ( EAnimPhysicsSound )ToolList_GetSelectIndex(g_EEData.PhysicsSoundTList); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // イベント時間変更ボタンの処理( リピート機能付き ) Flag = false; if( ToolButton_GetBottom( g_EEData.TimePlusTButton ) ) { if( !g_EEData.TimePlusButtonBottom ) { g_EEData.TimePlusButtonBottom = true; Flag = true; } g_EEData.TimePlusButtonBottomTime += StepTime; if( g_EEData.TimePlusButtonBottomTime > TIME_BUTTON_REPEAT ) { Flag = true; g_EEData.TimePlusButtonBottomTime -= TIME_BUTTON_LOOP_REPEAT; } } else { g_EEData.TimePlusButtonBottom = false; g_EEData.TimePlusButtonBottomTime = 0.0f; } if( Flag ) { // 加算ボタンが押されたらイベントの時間を加算する AEInfo->TimeI += ( int )ANIM_TIME_INT_SCALE / 2; AEInfo->TimeI = ( AEInfo->TimeI + ( ( int )ANIM_TIME_INT_SCALE / 2 ) - 1 ) / ( ( int )ANIM_TIME_INT_SCALE / 2 ) * ( int )ANIM_TIME_INT_SCALE / 2; AEInfo->TimeF = AEInfo->TimeI / ANIM_TIME_INT_SCALE; if( AEInfo->TimeF > TotalTime ) { AEInfo->TimeF = TotalTime; AEInfo->TimeI = ( int )( TotalTime * ANIM_TIME_INT_SCALE ); } // イベントを時間順にソートする SortEvent(); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } Flag = false; if( ToolButton_GetBottom( g_EEData.TimeMinusTButton ) ) { if( !g_EEData.TimeMinusButtonBottom ) { g_EEData.TimeMinusButtonBottom = true; Flag = true; } g_EEData.TimeMinusButtonBottomTime += StepTime; if( g_EEData.TimeMinusButtonBottomTime > TIME_BUTTON_REPEAT ) { Flag = true; g_EEData.TimeMinusButtonBottomTime -= TIME_BUTTON_LOOP_REPEAT; } } else { g_EEData.TimeMinusButtonBottom = false; g_EEData.TimeMinusButtonBottomTime = 0.0f; } if( Flag ) { // 減算ボタンが押されたらイベントの時間を加算する AEInfo->TimeI -= ( int )ANIM_TIME_INT_SCALE / 2; AEInfo->TimeI = ( AEInfo->TimeI + ( ( int )ANIM_TIME_INT_SCALE / 2 ) - 1 ) / ( ( int )ANIM_TIME_INT_SCALE / 2 ) * ( int )ANIM_TIME_INT_SCALE / 2; if( AEInfo->TimeI < 0 ) { AEInfo->TimeI = 0; } AEInfo->TimeF = AEInfo->TimeI / ANIM_TIME_INT_SCALE; // イベントを時間順にソートする SortEvent(); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // 攻撃番号を操作するボタンが押されたらイベントの攻撃番号を変更する if( ToolButton_GetClick( g_EEData.AttackNoPlusTButton, true ) ) { if( AEInfo->AttackNo == CHARA_ATTACK_MAX_NUM - 1 ) { AEInfo->AttackNo = 0; } else { AEInfo->AttackNo++; } // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } if( ToolButton_GetClick( g_EEData.AttackNoMinusTButton, true ) ) { if( AEInfo->AttackNo == 0 ) { AEInfo->AttackNo = CHARA_ATTACK_MAX_NUM - 1; } else { AEInfo->AttackNo--; } // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // 攻撃判定の起点となる3Dモデル中のフレームの番号を操作するボタンが // 押されたらフレームの番号を変更する if( ToolButton_GetClick( g_EEData.AttackPosPlusTButton, true ) ) { if( AEInfo->AttackPosIndex == CHARA_ATTACK_POS_MAX_NUM - 1 ) { AEInfo->AttackPosIndex = 0; } else { AEInfo->AttackPosIndex++; } // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } if( ToolButton_GetClick( g_EEData.AttackPosMinusTButton, true ) ) { if( AEInfo->AttackPosIndex == 0 ) { AEInfo->AttackPosIndex = CHARA_ATTACK_POS_MAX_NUM - 1; } else { AEInfo->AttackPosIndex--; } // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } } // イベントを追加するボタンが押されたらイベントを追加する if( ToolButton_GetClick( g_EEData.AddTButton, true ) ) { AEInfo = &AInfo->Event[ AInfo->EventNum ]; // 新しいイベントの情報を初期化 AEInfo->Type = EAnimEventType_Sound; AEInfo->PhysicsSound = EAnimPhysicsSound_Footstep; AEInfo->TimeF = 0.0f; AEInfo->TimeI = 0; memset( AEInfo->SoundPath, 0, sizeof( AEInfo->SoundPath ) ); AEInfo->SoundHandle = 0; // 編集対象のイベントを初期化する g_AEData.TargetEvent = 0; // イベントの数を増やす AInfo->EventNum++; // イベントを時間順にソートする SortEvent(); // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // イベントを削除するボタンが押されたら選択されているイベントを削除する if( ToolButton_GetClick( g_EEData.DelTButton, true ) ) { // イベントの数を減らす AInfo->EventNum--; // 末端のイベント以外を削除した場合は、削除したイベントの分だけ配列を詰める if( g_AEData.TargetEvent != AInfo->EventNum ) { memmove( &AInfo->Event[ g_AEData.TargetEvent ], &AInfo->Event[ g_AEData.TargetEvent + 1 ], ( AInfo->EventNum - g_AEData.TargetEvent ) * sizeof( SAnimEventInfo ) ); } // キャラクターモデルにアタッチしたアニメーションの再生時間をセットアップする SetupAttachAnimTime(); // アニメーションの情報が変更されたかどうかのフラグを立てる AInfo->Change = true; // イベントリストを更新する if( !EventEdit_SetupList() ) { return false; } } // アニメーションキャンセルを有効にするかどうかのリストの状態が変化した場合は // リストの選択を有効・無効の状態に反映する if( ToolList_GetChange( g_EEData.NextAnimEnableTList, true ) ) { g_AEData.NextAnimValid = ToolList_GetSelectIndex( g_EEData.NextAnimEnableTList ) == 1; } // アニメーションキャンセル後に再生するアニメーションのリストの状態が変化した場合は // キャンセル後に再生するアニメーションを変更する if( ToolList_GetChange( g_EEData.NextAnimListTList, true ) ) { g_AEData.NextAnim = g_AEData.EnableAnimList[ToolList_GetSelectIndex(g_EEData.NextAnimListTList)]; // キャラクターモデルにアタッチするアニメーションをセットアップする SetupAttachAnim(); } // 正常終了 return true; } // イベント編集処理の描画処理を行う void EventEdit_Render( void ) { SAnimInfo *AInfo; SAnimEventInfo *AEInfo; SCharaBaseInfo *CBInfo; int x; int i; int DrawLineColor; float TotalTime; CBInfo = CharaBase_GetInfo( g_AEData.TargetChara ); // イベント編集処理の説明文を描画する DrawString( 0, 0, "イベントを編集してください", GetColor( 255,255,255 ), GetColor( 0,0,0 ) ); // イベントマップのタイムライン線を描画 DrawLine( MAP_X, MAP_Y, MAP_X + MAP_WIDTH, MAP_Y, GetColor( 255,255,255 ) ); // イベントマップの両端部分の縦線を描画 DrawLine( MAP_X, MAP_Y - MAP_VLINE_HEIGHT, MAP_X, MAP_Y + MAP_VLINE_HEIGHT, GetColor( 255,255,255 ) ); DrawLine( MAP_X + MAP_WIDTH, MAP_Y - MAP_VLINE_HEIGHT, MAP_X + MAP_WIDTH, MAP_Y + MAP_VLINE_HEIGHT, GetColor( 255,255,255 ) ); TotalTime = MV1GetAnimTotalTime( CBInfo->AnimInfo[ g_AEData.TargetAnim ].Handle, 0 ); // アニメーションを再生している場合は現在の再生位置を示す縦線を描画 if( g_AEData.AnimPlay ) { x = ( int )( MAP_WIDTH * g_AEData.AnimPlayTime / TotalTime ); DrawLine( MAP_X + x, MAP_Y - MAP_PLAYTIMELINE_HEIGHT, MAP_X + x, MAP_Y + MAP_PLAYTIMELINE_HEIGHT, GetColor( 255,0,0 ), 4 ); } // 全イベントの時間の位置にイベントタイプ毎に色分けされた縦線を描画 AInfo = &CBInfo->AnimInfo[ g_AEData.TargetAnim ].Info; AEInfo = AInfo->Event; for( i = 0; i < AInfo->EventNum; i++, AEInfo++ ) { DrawLineColor = GetColor( g_EventLineColorTable[ AEInfo->Type ][ 0 ], g_EventLineColorTable[ AEInfo->Type ][ 1 ], g_EventLineColorTable[ AEInfo->Type ][ 2 ] ); x = ( int )( MAP_WIDTH * AEInfo->TimeF / TotalTime ); DrawLine( MAP_X + x, MAP_Y - MAP_EVENT_VLINE_HEIGHT, MAP_X + x, MAP_Y + MAP_EVENT_VLINE_HEIGHT, DrawLineColor ); } // アニメーションの総時間を描画 DrawFormatString( TOTAL_TIME_X, TOTAL_TIME_Y, GetColor( 255,255,255 ), "TotalTime:%.1f", TotalTime ); // イベントタイプがサウンド再生だった場合はサウンドファイルをドラッグ&ドロップ // すれば再生するサウンドを変更できる旨の説明文を描画する if( AInfo->EventNum > 0 && AInfo->Event[ g_AEData.TargetEvent ].Type == EAnimEventType_Sound ) { DrawString( 0, SCREEN_HEIGHT - 60, "Data\\Sound\\SEフォルダ内のファイル名の末尾が_00.wavのファイルをDrag&Dropするとサウンドが割り当てられます", GetColor( 255,255,255 ), GetColor( 0,0,0 ) ); } } // イベント編集処理の表示状態を変更する extern void EventEdit_SetVisible( // 新しい表示状態( true:表示する false:表示しない ) bool Visible ) { ToolVisible_SetVisible( g_EEData.TVisible, Visible ); } // イベント編集処理で使用するアニメーションキャンセル後に再生する // アニメーションリストを初期化する void EventEdit_InitializeNextAnimList( void ) { ToolList_Initialize( g_EEData.NextAnimListTList, g_EEData.NextAnimListTWindow ); } // イベント編集処理で使用するアニメーションキャンセル後に再生する // アニメーションリストのハンドルを取得する // 戻り値 : アニメキャンセル後に再生するアニメリストのハンドル int EventEdit_GetNextAnimListTListHandle( void ) { return g_EEData.NextAnimListTList; }