//################################################################################# // // BASE CLASS OF YOUR DLL interface // //################################################################################# #include "stdafx.h" #include "SCR.h" #include "SND.h" #include "sndld_s.h" // for SND_pstGetEventGroupLinkTable... #include "sndld_hy.h" // for SND_fn_czGetProjectTitle... #include "snddbg.h" // for SND_fn_pstGetSelectedResource && SND_fn_bDoesSupervisaterSelectResource #include "sndres.h" // for tdstBlockResourceMem type use #include "acp_base.h" // for CPA_Tooldllb class definition #include "incITF.h" // for CPA_Tooldllb class definition #include "SNinterf.hpp" #include "TSNEvent.h" #include "SIF.h" // Sound info server.. //#include "Sifloads.h" //for SIF_fn_pstGetSoundInfosDescriptor #include "x:\cpa\main\inc\_editid.h" //Object type names.. /* #include "ITF/cpasaveo.hpp" // For TSN_Event&SIF_InfoValue class definition #include "LST/cpalist.hpp" // for the CPA_List defined in the SIF_InfoType object #include "ITF/CPAProj.hpp" // for M_GetMainWnd() //static CList g_oListOfInstances; //private internal #define C_lEDST_Active 1 #define C_lEDST_Inactive 0 */ // the DLL global definition tdstDLLIdentity g_stSNDEDITIdentity; SNDEDIT_Interface* g_poSNDEDITInterface=NULL; //-------------------------------------------------------------------------------- // CONSTRUCTOR. // You must put here all your DLL interface definitions. //-------------------------------------------------------------------------------- SNDEDIT_Interface::SNDEDIT_Interface(void) { SetEditorInfo( "Sound", "Frédéric Décréau", "v6.0.0", "",""); // ************************** private internal m_p_stDLLIdentity = &g_stSNDEDITIdentity; // Name of your .INI file. // m_stBaseDLLDefinition.p_cIniName = NULL; // Does your DLL can output in main game view ? m_stBaseDLLDefinition.bCanOutputIn3DView = FALSE; // Does your DLL can be refresh by engine ? m_stBaseDLLDefinition.bCanBeRefreshedByEngine = FALSE; m_bEditorEnabled=FALSE; m_uiTimerId=NULL; } SNDEDIT_Interface::~SNDEDIT_Interface(void) { POSITION Pos; TSN_Event *pEvent; // delete events: Pos=NULL; while (pEvent=m_EdiEventList.GetNextElement(Pos)) delete pEvent; fn_vDestroyResList(); TSN_fn_bDesInitSoundInfos(); } void SNDEDIT_Interface::fn_vJustAfterRegistered(void) { int iTypeNum; int iNbTypes,iNbInfoTypes; CString *pa_csTypes; //******************************************************* //* Register the CPA_SaveObject types * //******************************************************* // Number of CPA_SaveObject types: 1 for sound events + 1 for each info type: iNbInfoTypes=SIF_fn_iGetSoundInfosCount(); iNbTypes=iNbInfoTypes+1; pa_csTypes= new CString[iNbTypes]; for (iTypeNum=0;iTypeNumUpdateStatus("Loading sound data",C_STATUSPANE_INFOS,C_STATUS_NORMAL); // Save and delete script callbacks on SndResourceM and SndEventM: pCallback=SCR_fnp_st_RdL0_GetRegisterCallback("SndResourceM",SCR_CRC_c_RdL0_ForSection); pOldSndResM_CB=pCallback->pfn_eCallback; pCallback=SCR_fnp_st_RdL0_GetRegisterCallback("SndEventM",SCR_CRC_c_RdL0_ForSection); pOldSndEventM_CB=pCallback->pfn_eCallback; SCR_fn_v_RdL0_DeleteRegisterCallback("SndResourceM",SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match); SCR_fn_v_RdL0_DeleteRegisterCallback("SndEventM",SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match); csName=SND_fn_czGetProjectTitle(); csName+=".sif"; TSN_fn_bInitSoundInfos(csName); // Scan event groups: // Get first list element: uiPos = 0; p_stTable=SND_pstGetEventGroupLinkTable(); SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value,uiPos,p_stValue, SCR_M_st_Link_GetDynamicArray(p_stTable)); while(p_stValue) // p_sValue is NULL at the end of the array { if(SCR_M_e_Link_GetState(p_stValue) != SCR_ELS_Link_Initialized) continue; // Get event group name: csName=SCR_M_p_sz_Link_GetKey(p_stValue); // Update status bar: csTemp.Format("Loading sound bank: %s",csName); M_GetMainWnd()->UpdateStatus((char*)(LPCTSTR)csTemp,C_STATUSPANE_INFOS,C_STATUS_NORMAL); csName+=".csb"; SCR_fnp_st_RdL0_AnalyseSection((char*)(LPCTSTR)csName, SCR_CDF_uw_Anl_Normal); uiPos++; SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value,uiPos,p_stValue, SCR_M_st_Link_GetDynamicArray(SND_pstGetEventGroupLinkTable())); } // Reset the script callbacks we deleted: unsigned char ucOldMemLevel = SCR_fn_uc_Mem_GetCurrentLevel(); SCR_fn_v_Mem_SetCurrentLevel(0); SCR_fn_v_RdL0_RegisterCallback("SndResourceM",pOldSndResM_CB,SCR_CRC_c_RdL0_ForSection); SCR_fn_v_RdL0_RegisterCallback("SndEventM",pOldSndEventM_CB,SCR_CRC_c_RdL0_ForSection); SCR_fn_v_Mem_SetCurrentLevel(ucOldMemLevel); // Sound load finished: M_GetMainWnd()->UpdateStatus("",C_STATUSPANE_INFOS,C_STATUS_NORMAL); }; void SNDEDIT_Interface::fn_vBeforeEngine() { if (!m_bEditorEnabled) return; ASSERT(m_uiTimerId==NULL); m_uiTimerId=timeSetEvent(10,10,m_fn_vTimerProc,NULL,TIME_ONESHOT); ASSERT(m_uiTimerId!=NULL); } void SNDEDIT_Interface::fn_vBeforeEditor() { char szPath[MAX_PATH]; MMRESULT mReturn; if (!m_bEditorEnabled) return; ASSERT(m_uiTimerId!=NULL); mReturn=timeKillEvent(m_uiTimerId); ASSERT(mReturn==TIMERR_NOERROR); m_uiTimerId=NULL; // Record modified resources: IResource IRes; LPDISPATCH lpDispatch; POSITION Pos; tdstBlockResourceMem* pResM; if (m_ModifiedResList.IsEmpty()) return; Pos=NULL; while (pResM=m_ModifiedResList.GetNextElement(Pos)) { // Find corresponding resource in editor: lpDispatch=m_IEditor.FindResFromEditorId(pResM->Id); if (lpDispatch!=NULL) { IRes.AttachDispatch(lpDispatch); // Change the volume in the editor: IRes.SetVolume(pResM->ucVolume); IRes.DetachDispatch(); } } // Open the sound project: GetTempPath(MAX_PATH,szPath); strcat(szPath,"\\"); strcat(szPath,"TSltemp.tmp"); SCR_fn_v_SvL1_RegisterNotify(szPath,mfn_vNotificationCallback,NULL,SCR_EA_Ntfy_AddOrRebuildSection); m_ModifiedResList.RemoveAll(); } void CALLBACK EXPORT SNDEDIT_Interface::m_fn_vTimerProc( UINT uID, // event ID UINT nMsg, // Reserved DWORD dwUser, // user data DWORD dw1,DWORD dw2 // Reserved ) { IResource IRes; tdstBlockResourceMem* pResM; long lTemp; POSITION Pos=NULL; BOOL bKeyPressed=FALSE; if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeUp)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=1; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeDown)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=-1; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeUpFast)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=10; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeDownFast)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=-10; } if (!bKeyPressed) goto procend_label; if (!SND_fn_bDoesSupervisaterSelectResource()) goto procend_label; pResM=SND_fn_pstGetSelectedResource(); if (pResM==NULL) goto procend_label; // Compute new volume and check bounds: lTemp+=(long)pResM->ucVolume; if ((lTemp<0)||(lTemp>127)) goto procend_label; // Change the volume in the game: pResM->ucVolume=(unsigned char)lTemp; if (g_poSNDEDITInterface->m_ModifiedResList.Find(pResM)==NULL) g_poSNDEDITInterface->m_ModifiedResList.AddTail(pResM); procend_label: //resend the timer: if (g_poSNDEDITInterface->m_uiTimerId!=NULL) { g_poSNDEDITInterface->m_uiTimerId=timeSetEvent(10,10,m_fn_vTimerProc,NULL,TIME_ONESHOT); ASSERT(g_poSNDEDITInterface->m_uiTimerId!=NULL); } } BOOL SNDEDIT_Interface::fn_bLoadBaseObject(CPA_BaseObject *p_oObject) { TSN_Event *pEvent=(TSN_Event *)p_oObject; return (pEvent->fn_bEngineLoad()); } BOOL SNDEDIT_Interface::fn_bDefineSubMenu(EDT_SubMenu *_pSubMenu) { switch(_pSubMenu->GetSubMenuType()) { case C_SubMenuEditor: break; case C_SubMenuTool: //AddAnEntry args: Owner,Text,Id,_bCheck,_bEnable. _pSubMenu->AddAnEntry(this,"Enable Sound Mixing",1,m_bEditorEnabled,TRUE); break; } return TRUE; } void SNDEDIT_Interface::_OnSubMenuCommand(EDT_SubMenu *_pSubMenu,UINT uiMsgId) { char szName[MAX_PATH],szPath[MAX_PATH]; switch (_pSubMenu->GetSubMenuType()) { case C_SubMenuEditor: break; case C_SubMenuTool: switch (uiMsgId) { case 1: //*********************************************** //* Initialize sound editor * //*********************************************** // OLE DLL initailisation: if (!AfxOleInit()) { AfxMessageBox("OLE Init failed. Check the OLE DLL versions."); return; } // Sound editor int: if (!m_IEditor.CreateDispatch(_T("SoundEditor.Document"))) { AfxMessageBox("Could not load the sound editor"); return; } // Open the sound project: strcpy(szName,SND_fn_czGetProjectTitle()); strcat(szName,".lcb"); SND_fn_vResolveFileName(szName,szPath); SND_fn_bGetCurrentDirectory(szName,MAX_PATH); strcat(szName,"\\"); strcat(szName,szPath); if (!m_IEditor.OpenDocument(szName)) { AfxMessageBox("Could not open the sound project"); return; } // *** Init Sound resource mixing keys // m_hSoundResourceVolumeUp = IPT_fn_hGetEntryActionHandle("SndResVolumeUp"); m_hSoundResourceVolumeDown= IPT_fn_hGetEntryActionHandle("SndResVolumeDown"); m_hSoundResourceVolumeUpFast= IPT_fn_hGetEntryActionHandle("SndResVolumeUpFast"); m_hSoundResourceVolumeDownFast= IPT_fn_hGetEntryActionHandle("SndResVolumeDownFast"); if (m_hSoundResourceVolumeUp==NULL) return; if (m_hSoundResourceVolumeDown==NULL) return; if (m_hSoundResourceVolumeUpFast==NULL) return; if (m_hSoundResourceVolumeDownFast==NULL) return; fn_vFillResList(); SND_fn_vSetResNameCallback(fn_czGetResNameFromEdId); m_bEditorEnabled=TRUE; break; } break; } } void SNDEDIT_Interface::mfn_vNotificationCallback(SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName, void *_pvData, SCR_tde_Ntfy_Action _eAction) { char szName[MAX_PATH],szPath[MAX_PATH]; switch (_eAction) { case SCR_EA_Ntfy_AddSection: case SCR_EA_Ntfy_ModifySection: case SCR_EA_Ntfy_RebuildSection: case SCR_EA_Ntfy_AddOrModifySection: case SCR_EA_Ntfy_AddOrRebuildSection: strcpy(szName,SND_fn_czGetProjectTitle()); strcat(szName,".lcb"); SND_fn_vResolveFileName(szName,szPath); SND_fn_bGetCurrentDirectory(szName,MAX_PATH); strcat(szName,"\\"); strcat(szName,szPath); g_poSNDEDITInterface->m_IEditor.SaveDocument(szName); break; case SCR_EA_Ntfy_DeleteIfExists: case SCR_EA_Ntfy_DeleteSection: case SCR_EA_Ntfy_Dummy: break; } } /* OLD FUNCTIONS: BOOL SNDEDIT_Interface::fn_bDefineSubMenu(EDT_SubMenu *_pSubMenu) { switch(_pSubMenu->GetSubMenuType()) { case C_SubMenuEditor: if (!fn_bIsCurrentEditor()) _pSubMenu->AddAnEntry(this, "Sound Editor", C_uiOpenID, FALSE); else _pSubMenu->AddAnEntry(this, "Sound Editor", C_uiCloseID, TRUE); break; case C_SubMenuTool: if (fn_bIsCurrentEditor()) { _pSubMenu->AddAnEntry(this,"Save sound data",1,FALSE); _pSubMenu->AddAnEntry(this,"Dump sound events in map",2,FALSE); _pSubMenu->AddAnEntry(this,"Check sample<->resource coherence",3,FALSE); _pSubMenu->AddAnEntry(this,"Load all sound banks",4,FALSE); } break; } return TRUE; } void SNDEDIT_Interface::_OnSubMenuCommand(EDT_SubMenu *_pSubMenu,UINT uiMsgId) { CString csDataPath; CString csLCBName,csSITName; POSITION Pos; SND_EventGroup *pGroup; switch (_pSubMenu->GetSubMenuType()) { case C_SubMenuEditor: switch (uiMsgId) { case C_uiOpenID: if (!fn_bIsCurrentEditor()) GetMainWorld()->fn_bActivateEditor(this, NULL); break; case C_uiCloseID: if (fn_bIsCurrentEditor()) GetMainWorld()->fn_bCloseEditor(this); break; } break; case C_SubMenuTool: switch (uiMsgId) { case 1: // Save Sound data: // Get the lcb name: csLCBName="ed_main.lcb"; csSITName="ed_main.sit"; csDataPath=m_Editor.m_fn_csGetSoundDirectory(); csLCBName=csDataPath+"ed_main.lcb"; m_Editor.m_fn_bSaveData((char*)(LPCTSTR)csLCBName); break; case 2: // Dump events in map: m_Editor.m_fn_vDumpEventsInMap(); break; case 3: //Check sample<->resource coherence: m_Editor.m_fn_vCheckSampleResCoherence(); break; case 4: //Load all sound banks: Pos=NULL; while (pGroup=m_Editor.m_fn_poGetEventGroupList()->GetNextElement(Pos)) if (!pGroup->fn_bIsLoaded()) pGroup->fn_bLoadData(); break; } break; } } void CALLBACK EXPORT SNDEDIT_Interface::m_fn_vTimerProc(HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent, // timer identification DWORD dwTime // system time ) { SND_ResourceView *pResView; SND_EdiRes* pRes; static SND_EdiRes* s_pEditedRes=NULL; tdstBlockResourceMem* pResM; long lTemp; unsigned long ulEvtGrpId; POSITION Pos=NULL; BOOL bKeyPressed=FALSE; if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeUp)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=1; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeDown)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=-1; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeUpFast)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=10; } if (IPT_fn_bIsJustValidated(g_poSNDEDITInterface->m_hSoundResourceVolumeDownFast)==IPT_C_TRUE) { bKeyPressed=TRUE; lTemp=-10; } if (bKeyPressed) { if (SND_fn_bDoesSupervisaterSelectResource()) { pResM=SND_fn_pstGetSelectedResource(); if (pResM==NULL) return; if ((s_pEditedRes==NULL)||(s_pEditedRes->GetStruct()!=pResM)) { // selected resource changed: get new corresponding editor res: ulEvtGrpId=HIWORD(pResM->Id); // Get event group id: // Get corresponding event group: SND_EventGroup* pGroup; Pos=NULL; while(pGroup=g_poSNDEDITInterface->m_Editor.m_fn_poGetEventGroupList()->GetNextElement(Pos)) if (pGroup->fn_ulGetId()==ulEvtGrpId) break; if (pGroup==NULL) return; // event group not found; // Load event group if not yet loaded: if (!pGroup->fn_bIsLoaded()) pGroup->fn_bLoadData(); // find resource in the group: Pos=NULL; while(s_pEditedRes=pGroup->m_ResList.GetNextElement(Pos)) if (s_pEditedRes->GetStruct()==pResM) break; if (s_pEditedRes==NULL) return; } // Add ltemp to this resource's volume: lTemp+=(long)s_pEditedRes->m_oBRDisk.ucVolume; if ((lTemp>=0)&&(lTemp<=127)) { s_pEditedRes->m_oBRDisk.ucVolume=(unsigned char)lTemp; s_pEditedRes->GetStruct()->ucVolume=(unsigned char)lTemp; s_pEditedRes->m_pGroup->fn_vNotifyRebuild(); MessageBeep(MB_ICONEXCLAMATION); pResView=(SND_ResourceView *)g_poSNDEDITInterface->m_pSplitFrame->m_fn_p_oGetPane(2); pResView->OnUpdate(0,0,0); } } else { pResView=(SND_ResourceView *)g_poSNDEDITInterface->m_pSplitFrame->m_fn_p_oGetPane(2); while (pRes=pResView->m_EditedResList.GetNextElement(Pos)) { // Add ltemp to this resource's volume: lTemp+=(long)pRes->m_oBRDisk.ucVolume; if ((lTemp>=0)&&(lTemp<=127)) { pRes->m_oBRDisk.ucVolume=(unsigned char)lTemp; pRes->GetStruct()->ucVolume=(unsigned char)lTemp; pRes->m_pGroup->fn_vNotifyRebuild(); MessageBeep(MB_ICONEXCLAMATION); pResView->OnUpdate(0,0,0); } } } } */ /* const char * SNDEDIT_Interface::fn_czGetResNameFromEdId(unsigned long _ulId) { if (g_poSNDEDITInterface->m_bEditorEnabled==FALSE) return ""; IResource IRes; LPDISPATCH lpDispatch; CString csName; // Find corresponding resource in editor: lpDispatch=g_poSNDEDITInterface->m_IEditor.FindResFromEditorId(_ulId); if (lpDispatch==NULL) return "Unknown Id"; IRes.AttachDispatch(lpDispatch); csName=IRes.GetName(); IRes.DetachDispatch(); return csName; } */ const char * SNDEDIT_Interface::fn_czGetResNameFromEdId(unsigned long _ulId) { short wEventGroupId,wResId; POSITION Pos; TSN_ResList *pResList; TSN_Res *pRes; wEventGroupId=HIWORD(_ulId); wResId=LOWORD(_ulId); if (g_poSNDEDITInterface->m_bEditorEnabled==FALSE) return ""; Pos=NULL; while (pResList=g_poSNDEDITInterface->m_ResListList.GetNextElement(Pos)) if (pResList->m_wId==wEventGroupId) break; if (pResList==NULL) return "Unknown Id"; Pos=NULL; while (pRes=pResList->m_ResList.GetNextElement(Pos)) if (pRes->m_wId==wResId) break; if (pRes==NULL) return "Unknown Id"; return pRes->m_csName; } void SNDEDIT_Interface::fn_vFillResList() { IEventGroups IGroups; IEventGroup IGroup; IResources IResList; TSN_ResList *pResList; TSN_Res *pRes; IResource IRes; int iNbGroups,iGroupNum,iNbRes,iResNum; IGroups.AttachDispatch(m_IEditor.GetEventGroups()); iNbGroups=IGroups.GetCount(); for (iGroupNum=0;iGroupNumm_csName=IGroup.GetName(); pResList->m_wId=(short)IGroup.GetId(); m_ResListList.AddTail(pResList); IResList.AttachDispatch(IGroup.GetResources()); iNbRes=IResList.GetCount(); for (iResNum=0;iResNumm_csName=IRes.GetName(); pRes->m_wId=(short)IRes.GetId(); pResList->m_ResList.AddTail(pRes); IRes.DetachDispatch(); }// end group scan IGroup.DetachDispatch(); }// end group scan } void SNDEDIT_Interface::fn_vDestroyResList() { POSITION Pos,SubPos; TSN_ResList *pResList; TSN_Res *pRes; Pos=NULL; while (pResList=m_ResListList.GetNextElement(Pos)) { SubPos=NULL; while (pRes=pResList->m_ResList.GetNextElement(SubPos)) delete pRes; delete pResList; } }