/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ // AdvancedAnimSheet.cpp : implementation file // #include "stdafx.h" #include "w3dview.h" #include "W3dViewDoc.h" #include "AdvancedAnimSheet.h" #include "AssetMgr.h" #include "HAnim.h" #include "HTree.h" #include "Utils.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // QSort comparison function for HAnimClass pointers. // Will compare their names. static int anim_name_compare (const void *arg1, const void *arg2) { ASSERT(arg1 != NULL); ASSERT(arg2 != NULL); HAnimClass *a1 = *(HAnimClass**)arg1; HAnimClass *a2 = *(HAnimClass**)arg2; return _stricmp( a1->Get_Name(), a2->Get_Name() ); } ///////////////////////////////////////////////////////////////////////////// // CAdvancedAnimSheet IMPLEMENT_DYNAMIC(CAdvancedAnimSheet, CPropertySheet) CAdvancedAnimSheet::CAdvancedAnimSheet(CWnd* pParentWnd, UINT iSelectPage) : CPropertySheet("Advanced Animation", pParentWnd, iSelectPage), m_MixingPage(this), m_ReportPage(this), AnimsValid(false), AnimCount(0) { // Blank out the array of animation pointers. ZeroMemory(Anims, sizeof(Anims)); // Add the property pages into this property sheet. AddPage(&m_MixingPage); AddPage(&m_ReportPage); } CAdvancedAnimSheet::~CAdvancedAnimSheet() { if (AnimsValid) { for (int i = 0; i < AnimCount; i++) { MEMBER_RELEASE(Anims[i]); } AnimsValid = false; AnimCount = 0; } } BEGIN_MESSAGE_MAP(CAdvancedAnimSheet, CPropertySheet) //{{AFX_MSG_MAP(CAdvancedAnimSheet) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAdvancedAnimSheet message handlers int CAdvancedAnimSheet::GetAnimCount (void) { if (AnimsValid) return AnimCount; LoadAnims(); if (AnimsValid) return AnimCount; else return 0; } HAnimClass ** CAdvancedAnimSheet::GetAnims (void) { if (AnimsValid) return Anims; LoadAnims(); // Return the array regardless of validity. If the entries are // invalid, they'll all be NULL, but the array itself is cool. return Anims; } void CAdvancedAnimSheet::LoadAnims (void) { // Get the current render object and it's HTree. If it doesn't have // an HTree, then it's not animating and we're not interested. RenderObjClass *robj = ::GetCurrentDocument()->GetDisplayedObject(); if (robj == NULL) return; const HTreeClass *htree = robj->Get_HTree(); if (htree == NULL) return; const char *htree_name = htree->Get_Name(); /* ** Figure out which animations apply to the current object, and ** add each one to the array of animations which we will later sort. */ // Get an iterator from the asset manager that we can // use to enumerate the currently loaded assets AssetIterator *pAnimEnum = WW3DAssetManager::Get_Instance()->Create_HAnim_Iterator(); ASSERT(pAnimEnum != NULL); if (pAnimEnum) { // Loop through all the animations in the manager for (pAnimEnum->First(); pAnimEnum->Is_Done() == FALSE; pAnimEnum->Next()) { LPCTSTR pszAnimName = pAnimEnum->Current_Item_Name(); // Get an instance of the animation object HAnimClass *pHierarchyAnim = WW3DAssetManager::Get_Instance()->Get_HAnim(pszAnimName); ASSERT(pHierarchyAnim != NULL); if (pHierarchyAnim) { // Does this animation apply to the current model's HTree? if (stricmp(htree_name, pHierarchyAnim->Get_HName()) == 0) { // Add this Anims pointer to the array. if (AnimCount < MAX_REPORT_ANIMS) { MEMBER_ADD(Anims[AnimCount], pHierarchyAnim); AnimCount++; } else { char msg[256]; sprintf(msg, "Error: Only %d animations are supported in this report. " " There are more than that loaded...", MAX_REPORT_ANIMS); MessageBox(msg, "Too Many Animations"); break; } } // Release our hold on this animation. MEMBER_RELEASE(pHierarchyAnim); } } // Free the object delete pAnimEnum; pAnimEnum = NULL; } /* ** Sort the array of animations in alphabetical order. */ qsort(Anims, AnimCount, sizeof(HAnimClass*), anim_name_compare); AnimsValid = true; }