| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- /*
- ** 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 <http://www.gnu.org/licenses/>.
- */
- #include "StdAfx.h"
- #include "priv.h"
- #include "shellext.h"
- #include "resource.h"
- #include <stdio.h>
- #include "wdump.h"
- #include "WdumpDoc.h"
- #include "W3D_File.h"
- #include <commctrl.h>
- //===============================================================
- // *********** G L O B A L S ************************
- extern UINT g_DllRefCount; // Reference count of this DLL.
- extern HINSTANCE g_DllInstance; // Handle to this DLL itself.
- //===============================================================
- // *********** F U N C T I O N S *********************
- ///////////////////////////////////////
- UINT CALLBACK W3DPageCallback(HWND hWnd,
- UINT uMessage,
- LPPROPSHEETPAGE ppsp){
- switch(uMessage){
- case PSPCB_CREATE:
- return TRUE;
- case PSPCB_RELEASE:{
- if (ppsp->lParam){
- ((LPCSHELLEXT)(ppsp->lParam))->Release();
- }
- return TRUE;
- }
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void ShowHideControls(HWND hDlg, bool show){
- HWND hControl = GetWindow(hDlg, GW_CHILD);
- while(hControl != NULL){
- ShowWindow(hControl,show?SW_SHOW:SW_HIDE);
- hControl = GetWindow(hControl, GW_HWNDNEXT);
- }
- ShowWindow(GetDlgItem(hDlg, IDC_NODATA),show?SW_HIDE:SW_SHOW );
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void GetItemName(ChunkItem *pItem, int id_of_interest, void* pInfo, int sizeof_struct, int& found ){
- if(pItem->ID == id_of_interest){
- BYTE *byte_ptr = (BYTE*) pInfo;
- byte_ptr += sizeof_struct* found;
- memcpy(byte_ptr,pItem->Data,pItem->Length);
- found ++;
- }
- //Get all Sibitems for this item
- POSITION p = pItem->Chunks.GetHeadPosition();
- while(p != 0) {
- ChunkItem *subitem = pItem->Chunks.GetNext(p);
- GetItemName(subitem, id_of_interest, pInfo, sizeof_struct,found);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- BOOL CALLBACK AnimPageDlgProc(HWND hDlg,UINT uMessage, WPARAM wParam, LPARAM lParam){
- LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
- UINT iIndex=0;
- LPCSHELLEXT lpcs;
- char buf[MAX_PATH];
- switch (uMessage){
- case WM_INITDIALOG:{
- SetWindowLong(hDlg, DWL_USER, lParam);
- psp = (LPPROPSHEETPAGE)lParam;
- lpcs = (LPCSHELLEXT)psp->lParam;
- if(!lpcs->m_FileInMemory){
- lpcs->Read_SelectedFile();
- }
- ChunkData* pData = &(lpcs->m_WdumpDocument.m_ChunkData);
- assert(pData);
- POSITION ptr = pData->Chunks.GetHeadPosition();;
- ASSERT(ptr);
- W3dAnimHeaderStruct* pAnim = lpcs->m_AnimInfos;
- int id_of_interest = W3D_CHUNK_ANIMATION_HEADER;
- int sizeof_struct = sizeof W3dAnimHeaderStruct;
- int found_animations(0);
- while(ptr){
- ChunkItem *pItem = pData->Chunks.GetNext(ptr);
- GetItemName(pItem, id_of_interest, (void*)lpcs->m_AnimInfos, sizeof_struct, found_animations );
- }
- if(found_animations){
- //So far assuming only one animation per file
- SetDlgItemText(hDlg, IDC_ANIMNAME, pAnim->Name);
- SetDlgItemText(hDlg, IDC_HNAME, pAnim->HierarchyName);
- SetDlgItemInt(hDlg, IDC_NUMFRAMES, pAnim->NumFrames,FALSE);
- //FrameRate
- sprintf(buf,"%i fps",pAnim->FrameRate,FALSE);
- SetDlgItemText(hDlg, IDC_FRAMERATE, buf);
- //SetDlgItemInt(hDlg, IDC_FRAMERATE, pAnim->FrameRate,FALSE);
- //version
- sprintf(buf,"%d.%d",W3D_GET_MAJOR_VERSION(pAnim->Version),W3D_GET_MINOR_VERSION(pAnim->Version));
- SetDlgItemText(hDlg, IDC_ANIMVERSION, buf);
- }
- //Hierarchies
- ptr = pData->Chunks.GetHeadPosition();;
- ASSERT(ptr);
- id_of_interest = W3D_CHUNK_HIERARCHY_HEADER;
- //So far assuming only one hierarchy per file
- W3dHierarchyStruct* pHInfo = lpcs->m_Hierarchies;
- ASSERT(pHInfo);
- sizeof_struct = sizeof W3dHierarchyStruct;
- int found_hierarchies(0);
- while(ptr){
- ChunkItem *pItem = pData->Chunks.GetNext(ptr);
- GetItemName(pItem, id_of_interest, (void*)pHInfo, sizeof_struct, found_hierarchies );
- }
- if(found_hierarchies){
- SetDlgItemText(hDlg, IDC_HIERARCHYNAME, pHInfo->Name);
- SetDlgItemInt(hDlg, IDC_NUMPIVOTS, pHInfo->NumPivots,FALSE);
- sprintf(buf,"%d.%d",W3D_GET_MAJOR_VERSION(pHInfo->Version),W3D_GET_MINOR_VERSION(pHInfo->Version));
- SetDlgItemText(hDlg, IDC_HIERARCHYVERSION, buf);
- sprintf(buf, "(%.3f, %.3f, %.3f)", pHInfo->Center.X, pHInfo->Center.Y, pHInfo->Center.Z);
- SetDlgItemText(hDlg, IDC_HCENTER, buf);
- }
- ShowHideControls(hDlg, (found_animations + found_hierarchies)!= 0);
- break;
- }
- case WM_DESTROY:{
- RemoveProp(hDlg, "ID");
- break;
- }
- case WM_COMMAND:
- switch (LOWORD(wParam)){
- case IDC_TOP3D:
- //SetProp(hDlg, "ID", (HANDLE)lParam);
- break;
- default:
- break;
- }
- break;
- case WM_NOTIFY:
- switch (((NMHDR FAR *)lParam)->code){
- case PSN_SETACTIVE:
- break;
- case PSN_APPLY:
- //User has clicked the OK or Apply button so we'll
- //update the icon information in the .W3D file
- lpcs = (LPCSHELLEXT)psp->lParam;
- //Ask the shell to refresh the icon list...
- //SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0, 0);
- break;
- default:
- break;
- }
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- //=====================================================================================================
- void SetDlgMeshParams(HWND hDlg, W3dMeshHeader3Struct*pInfo){
- SetDlgItemText(hDlg,IDC_MESHNAME,pInfo->MeshName);
- SetDlgItemText(hDlg,IDC_CONTAINER,pInfo->ContainerName);
- SetDlgItemInt(hDlg,IDC_NUM_MATERIALS, pInfo->NumMaterials,FALSE);
- SetDlgItemInt(hDlg,IDC_NUM_POLYS, pInfo->NumTris,FALSE);
- SetDlgItemInt(hDlg,IDC_NUM_VERTICES, pInfo->NumVertices, FALSE);
- SetDlgItemInt(hDlg,IDC_NUM_MATERIALS, pInfo->NumMaterials,FALSE);
- char msg[MAX_PATH];
- sprintf(msg, "%.3f", pInfo->SphRadius);
- SetDlgItemText(hDlg,IDC_SPHERERADIUS,msg);
- //3D Coords
- //Center
- sprintf(msg, "(%.3f, %.3f, %.3f)", pInfo->SphCenter.X, pInfo->SphCenter.Y, pInfo->SphCenter.Z);
- SetDlgItemText(hDlg, IDC_SPHERECENTER, msg);
- //Min
- sprintf(msg, "(%.3f, %.3f, %.3f)", pInfo->Min.X, pInfo->Min.Y, pInfo->Min.Z);
- SetDlgItemText(hDlg, IDC_MINDIM, msg);
- //Max
- sprintf(msg, "(%.3f, %.3f, %.3f)", pInfo->Max.X, pInfo->Max.Y, pInfo->Max.Z);
- SetDlgItemText(hDlg, IDC_MAXDIM, msg);
- sprintf(msg,"%d.%d",W3D_GET_MAJOR_VERSION(pInfo->Version),W3D_GET_MINOR_VERSION(pInfo->Version));
- SetDlgItemText(hDlg, IDC_VERSION, msg);
- }
- //==========================================================================================================
- BOOL CALLBACK MeshPageDlgProc(HWND hDlg,UINT uMessage, WPARAM wParam, LPARAM lParam){
- LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
- UINT iIndex=0;
- LPCSHELLEXT lpcs;
- switch (uMessage){
- case WM_INITDIALOG:{
- SetWindowLong(hDlg, DWL_USER, lParam);
- psp = (LPPROPSHEETPAGE)lParam;
- lpcs = (LPCSHELLEXT)psp->lParam;
- if(!lpcs->m_FileInMemory){
- lpcs->Read_SelectedFile();
- }
- ChunkData* pData = &(lpcs->m_WdumpDocument.m_ChunkData);
- assert(pData);
- POSITION ptr = pData->Chunks.GetHeadPosition();
- ASSERT(ptr);
- //Look for mesh headers
- W3dMeshHeader3Struct* pInfo = lpcs->m_Meshes;
- int id_of_interest = W3D_CHUNK_MESH_HEADER3;
- int sizeof_struct = sizeof W3dMeshHeader3Struct;
- while(ptr){
- ChunkItem *pItem = pData->Chunks.GetNext(ptr);
- ASSERT(lpcs->m_FoundMeshes < MAX_MESH);
- GetItemName(pItem, id_of_interest, (void*)(pInfo),sizeof_struct, lpcs->m_FoundMeshes );
- }
- if(lpcs->m_FoundMeshes){
- SetDlgItemInt(hDlg,IDC_MESHNUMBER, 0,FALSE);
- //Look for Textures
- char pTextureInfo[MAX_TEXUTRE_NAME_LEN * MAX_MESH];
- id_of_interest = W3D_CHUNK_TEXTURE_NAME;
- int found_textures(0);
- int sizeof_struct = MAX_TEXUTRE_NAME_LEN;
- ptr = pData->Chunks.GetHeadPosition();
- while(ptr){
- ChunkItem *pItem = pData->Chunks.GetNext(ptr);
- GetItemName(pItem, id_of_interest, (void*)pTextureInfo, sizeof_struct, found_textures );
- }
- for(int t_count(0); t_count < found_textures; t_count ++){
- if(lpcs->NotAdded(&(pTextureInfo[t_count*MAX_TEXUTRE_NAME_LEN]))){
- char* text = lpcs->m_Textures[lpcs->m_NumAdded-1].LockBuffer();
- SendDlgItemMessage(hDlg, IDC_TEXTURELIST, LB_ADDSTRING,(WPARAM) 0L, (LPARAM)text);//(pTextureInfo[t_count].name)) ;
- lpcs->m_Textures[lpcs->m_NumAdded-1].ReleaseBuffer();
- }
- }
- SetDlgItemInt(hDlg,IDC_NUM_MESHES, lpcs->m_FoundMeshes,FALSE);
- SetDlgMeshParams(hDlg, pInfo);
- //Set Spin range
- SendDlgItemMessage(hDlg, IDC_MESHSPIN, UDM_SETRANGE, (WPARAM)0L, (LPARAM)MAKELONG(lpcs->m_FoundMeshes-1,0));
- }
- ShowHideControls(hDlg, lpcs->m_FoundMeshes != 0);
- break;
- }
- case WM_DESTROY:
- RemoveProp(hDlg, "ID");
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam)){
- case IDC_TOP3D:
- //SetProp(hDlg, "ID", (HANDLE)lParam);
- break;
- default:
- break;
- }
- break;
- case WM_NOTIFY:
- lpcs = (LPCSHELLEXT)psp->lParam;
- switch (((NMHDR FAR *)lParam)->code){
- case PSN_SETACTIVE:
- break;
- case PSN_APPLY:
- //Ask the shell to refresh the icon list...
- SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0, 0);
- break;
- case UDN_DELTAPOS:{
- lpcs = (LPCSHELLEXT)psp->lParam;
- W3dMeshHeader3Struct* pInfo = lpcs->m_Meshes;
- LPNMUPDOWN lpUD = (LPNMUPDOWN) lParam;
- int mesh_num = lpUD->iDelta + lpUD->iPos;
- if(mesh_num >= 0 && mesh_num < lpcs->m_FoundMeshes){
- SetDlgMeshParams(hDlg, pInfo+mesh_num);
- }
- break;
- }
- default:
- break;
- }
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////
- BOOL CALLBACK PreviewPageDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam){
- LPPROPSHEETPAGE psp=(LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
- UINT iIndex(0);
- LPCSHELLEXT lpcs;
- switch (uMessage){
- case WM_INITDIALOG:{
- SetWindowLong(hDlg, DWL_USER, lParam);
- psp = (LPPROPSHEETPAGE)lParam;
- lpcs = (LPCSHELLEXT)psp->lParam;
- if(!lpcs->m_FileInMemory){
- lpcs->Read_SelectedFile();
- }
- break;
- }
- case WM_DESTROY:{
- RemoveProp(hDlg, "ID");
- break;
- }
- case WM_COMMAND:
- switch (LOWORD(wParam)){
- case IDC_TOP3D:
- //SetProp(hDlg, "ID", (HANDLE)lParam);
- break;
- default:
- break;
- }
- break;
- case WM_NOTIFY:
- switch (((NMHDR FAR *)lParam)->code){
- case PSN_SETACTIVE:
- break;
- case PSN_APPLY:
- //User has clicked the OK or Apply button so we'll
- //update the icon information in the .W3D file
- lpcs = (LPCSHELLEXT)psp->lParam;
- //Ask the shell to refresh the icon list...
- SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0, 0);
- break;
- default:
- break;
- }
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- // PURPOSE: Called by the shell just before the property sheet is displayed.
- STDMETHODIMP CShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, //Pointer to the Shell's AddPage function
- LPARAM lParam){ //Passed as second parameter to lpfnAddPage
- m_FileInMemory = false;
- PROPSHEETPAGE psp;
- HPROPSHEETPAGE hpage;
- FORMATETC fmte = {CF_HDROP,(DVTARGETDEVICE FAR *)NULL,DVASPECT_CONTENT,-1, TYMED_HGLOBAL };
- STGMEDIUM medium;
- HRESULT hres = 0;
- // char buf[MAX_PATH];
- if (m_pDataObj){ //Paranoid check, m_pDataObj should have something by now...
- hres = m_pDataObj->GetData(&fmte, &medium);
- }
- if (SUCCEEDED(hres)){
- //Find out how many files the user has selected...
- UINT cbFiles = 0;
- LPCSHELLEXT lpcsext = this;
- if (medium.hGlobal){
- cbFiles = DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, 0, 0);
- }
- if (cbFiles < 2){
- if (cbFiles){
- DragQueryFile((HDROP)medium.hGlobal,0, m_SelectedFile, sizeof(m_SelectedFile));
- }
- psp.dwSize = sizeof(psp); // no extra data.
- psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
- psp.hInstance = g_DllInstance;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_MESH);
- psp.hIcon = 0;
- psp.pszTitle = " Meshes ";
- psp.pfnDlgProc = MeshPageDlgProc;
- psp.pcRefParent = &g_DllRefCount;
- psp.pfnCallback = W3DPageCallback;
- psp.lParam = (LPARAM)lpcsext;
- AddRef();
- hpage = CreatePropertySheetPage(&psp);
- if(hpage){
- if (!lpfnAddPage(hpage, lParam)){
- DestroyPropertySheetPage(hpage);
- Release();
- }
- }
- //Animation Page
- psp.pszTemplate = MAKEINTRESOURCE(IDD_ANIMPAGE);
- psp.pszTitle = "Animations";
- psp.pfnDlgProc = AnimPageDlgProc;
- AddRef();
- hpage = CreatePropertySheetPage(&psp);
- if(hpage){
- if (!lpfnAddPage(hpage, lParam)){
- DestroyPropertySheetPage(hpage);
- Release();
- }
- }
- //Preview Page
- psp.pszTemplate = MAKEINTRESOURCE(IDD_PREVIEW);
- psp.pszTitle = " Preview ";
- psp.pfnDlgProc = PreviewPageDlgProc;
- AddRef();
- hpage = CreatePropertySheetPage(&psp);
- if(hpage){
- if (!lpfnAddPage(hpage, lParam)){
- DestroyPropertySheetPage(hpage);
- Release();
- }
- }
- }
- }
- return NOERROR;
- }
- // PURPOSE: Called by the shell only for Control Panel property sheet
- STDMETHODIMP CShellExt::ReplacePage(UINT uPageID, //ID of page to be replaced
- LPFNADDPROPSHEETPAGE lpfnReplaceWith, //Pointer to the Shell's Replace function
- LPARAM lParam){ //Passed as second parameter to lpfnReplaceWith
- return E_FAIL;//we don't support this function. It should never be
- }
|