// Filename:- wintalk.cpp // // a module containing code for talking to other windows apps via a shared memory space... // #include "stdafx.h" #include "includes.h" //#include #include "CommArea.h" // #include "wintalk.h" extern bool Document_ModelLoadPrimary(LPCSTR psFilename); static LPCSTR FindWhitespace(LPCSTR psString) { while (*psString && !isspace(*psString)) psString++; return psString; } static LPCSTR SkipWhitespace(LPCSTR psString) { while (isspace(*psString)) psString++; return psString; } static void TrimFirstSpace(char *psString) { *((char*)FindWhitespace(psString))='\0'; } // every case here must either do CommArea_CommandAck(...) or CommArea_CommandError(...), // failure to do this is amazingly bad. // // return TRUE = app exit requested // static bool HandleCommands(LPCSTR psString, byte *pbCommandData, int iCommandDataSize) { static bool bAppExitWanted = false; if (bAppExitWanted) return true; // refuse to listen to any more commands #define IF_ARG(string) if (!strncmp(psArg,string,strlen(string))) #define NEXT_ARG SkipWhitespace(FindWhitespace(psArg)) #define READ_ARG(_arg,_destbuffer) {strncpy(_destbuffer,_arg,sizeof(_destbuffer)-1);_destbuffer[sizeof(_destbuffer)-1]='\0';TrimFirstSpace(_destbuffer);} LPCSTR psArg = psString; IF_ARG("model_loadprimary") { psArg = NEXT_ARG; if (Document_ModelLoadPrimary( psArg )) { CommArea_CommandAck(va("%d",AppVars.hModelLastLoaded)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("quit") { CommArea_CommandAck(); bAppExitWanted = true; } else IF_ARG("model_loadbolton") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; char sBoltName[1024]; READ_ARG(psArg,sBoltName); psArg = NEXT_ARG; // psFullPathedFilename if (Model_LoadBoltOn(psArg, hModel, sBoltName, true, true)) // bBoltIsBone, bBoltReplacesAllExisting { CommArea_CommandAck(va("%d",AppVars.hModelLastLoaded)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_addbolton") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; char sBoltName[1024]; READ_ARG(psArg,sBoltName); psArg = NEXT_ARG; // psFullPathedFilename if (Model_LoadBoltOn(psArg, hModel, sBoltName, true, false)) // bBoltIsBone, bBoltReplacesAllExisting { CommArea_CommandAck(va("%d",AppVars.hModelLastLoaded)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_deletebolton") // { psArg = NEXT_ARG; ModelHandle_t hModelBoltOn = (ModelHandle_t) atoi(psArg); if (Model_DeleteBoltOn(hModelBoltOn)) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_loadsurfacebolton") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; char sBoltName[1024]; READ_ARG(psArg,sBoltName); psArg = NEXT_ARG; // psFullPathedFilename if (Model_LoadBoltOn(psArg, hModel, sBoltName, false, true)) // bBoltIsBone, bBoltReplacesAllExisting { CommArea_CommandAck(va("%d",AppVars.hModelLastLoaded)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_addsurfacebolton") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; char sBoltName[1024]; READ_ARG(psArg,sBoltName); psArg = NEXT_ARG; // psFullPathedFilename if (Model_LoadBoltOn(psArg, hModel, sBoltName, false, false)) // bBoltIsBone, bBoltReplacesAllExisting { CommArea_CommandAck(va("%d",AppVars.hModelLastLoaded)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_getnumbonealiases") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); int iAliases = Model_GetNumBoneAliases(hModel); CommArea_CommandAck(va("%d",iAliases)); } else IF_ARG("model_getbonealias") // <%d = index> (answer is "realname" "aliasname") { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; int iAliasNum = atoi(psArg); string strReal,strAlias; if (Model_GetBoneAliasPair(hModel, iAliasNum, strReal, strAlias)) { CommArea_CommandAck(va("%s %s",strReal.c_str(),strAlias.c_str())); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_getnumsequences") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); int iSequences = Model_GetNumSequences(hModel); CommArea_CommandAck(va("%d",iSequences)); } else IF_ARG("model_getsequence") // <%d = sequencenum> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; int iSequenceNum = atoi(psArg); LPCSTR psString = Model_GetSequenceString(hModel, iSequenceNum); if (psString) { CommArea_CommandAck(va("%s",psString)); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_locksequence") // <%d = sequencenum> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; int iSequenceNum = atoi(psArg); bool bOk = Model_Sequence_Lock(hModel, iSequenceNum, true); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_locksequence_secondary") // <%d = sequencenum> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; int iSequenceNum = atoi(psArg); bool bOk = Model_Sequence_Lock(hModel, iSequenceNum, false); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_unlocksequences") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); bool bOk = Model_Sequence_UnLock(hModel, true); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_unlocksequences_secondary") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); bool bOk = Model_Sequence_UnLock(hModel, false); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_bonename_secondarystart") // <%s = bonename> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; bool bOk = Model_SetSecondaryAnimStart(hModel, psArg); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_clear_secondarystart") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); bool bOk = Model_SetSecondaryAnimStart(hModel, -1); if (bOk) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_highlightbone") // <%s = bonename, else "#all" / "#none" / "#aliased"> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; bool bSuccess = false; if (!stricmp(psArg,"#aliased")) { bSuccess = Model_SetBoneHighlight(hModel, iITEMHIGHLIGHT_ALIASED); } else if (!stricmp(psArg,"#all")) { bSuccess = Model_SetBoneHighlight(hModel, iITEMHIGHLIGHT_ALL); } else if (!stricmp(psArg,"#none")) { bSuccess = Model_SetBoneHighlight(hModel, iITEMHIGHLIGHT_NONE); } else { bSuccess = Model_SetBoneHighlight(hModel, psArg); } if (bSuccess) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("model_highlightsurface") // <%s = surfacename, else "#all" or "#none"> { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); psArg = NEXT_ARG; bool bSuccess = false; if (!stricmp(psArg,"#tags")) { bSuccess = Model_SetSurfaceHighlight(hModel, iITEMHIGHLIGHT_ALL_TAGSURFACES); } else if (!stricmp(psArg,"#all")) { bSuccess = Model_SetSurfaceHighlight(hModel, iITEMHIGHLIGHT_ALL); } else if (!stricmp(psArg,"#none")) { bSuccess = Model_SetSurfaceHighlight(hModel, iITEMHIGHLIGHT_NONE); } else { bSuccess = Model_SetSurfaceHighlight(hModel, psArg); } if (bSuccess) { CommArea_CommandAck(); } else { CommArea_CommandError(va("ModView: Failed command: \"%s\"", psString)); } } else IF_ARG("modeltree_getrootsurface") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); // for this command, just send back whatever the answer is without validating... // HTREEITEM hTreeItem = ModelTree_GetRootSurface(hModel); CommArea_CommandAck(va("%d",hTreeItem)); } else IF_ARG("modeltree_getrootbone") // { psArg = NEXT_ARG; ModelHandle_t hModel = (ModelHandle_t) atoi(psArg); // for this command, just send back whatever the answer is without validating... // HTREEITEM hTreeItem = ModelTree_GetRootBone(hModel); CommArea_CommandAck(va("%d",hTreeItem)); } else // this version MUST be the first of the two, or the shorter one will early-match even a long command IF_ARG("modeltree_getitemtextpure") // "...pure" will skip stuff like "////" for disabled surfaces { psArg = NEXT_ARG; HTREEITEM hTreeItem = (HTREEITEM) atoi(psArg); LPCSTR psText = ModelTree_GetItemText(hTreeItem,true); CommArea_CommandAck(psText); } else IF_ARG("modeltree_getitemtext") { psArg = NEXT_ARG; HTREEITEM hTreeItem = (HTREEITEM) atoi(psArg); LPCSTR psText = ModelTree_GetItemText(hTreeItem); CommArea_CommandAck(psText); } else IF_ARG("modeltree_getchilditem") { psArg = NEXT_ARG; HTREEITEM hTreeItem = (HTREEITEM) atoi(psArg); hTreeItem = ModelTree_GetChildItem(hTreeItem); CommArea_CommandAck(va("%d",hTreeItem)); } else IF_ARG("modeltree_getnextsiblingitem") { psArg = NEXT_ARG; HTREEITEM hTreeItem = (HTREEITEM) atoi(psArg); hTreeItem = ModelTree_GetNextSiblingItem(hTreeItem); CommArea_CommandAck(va("%d",hTreeItem)); } else IF_ARG("errorbox_disable") { gbErrorBox_Inhibit = true; CommArea_CommandAck(); } else IF_ARG("errorbox_enable") { gbErrorBox_Inhibit = false; CommArea_CommandAck(); } else IF_ARG("getlasterror") { CommArea_CommandAck(ModView_GetLastError()); } else IF_ARG("startanimwrap") // must be BEFORE "startanim" because of strncmp()! { Model_StartAnim(true); CommArea_CommandAck(); } else IF_ARG("startanim") { Model_StartAnim(); CommArea_CommandAck(); } else IF_ARG("stopanim") { Model_StopAnim(); CommArea_CommandAck(); } else { // unknown command... // CommArea_CommandError(va("ModView: Unknown command \"%s\"", psString)); } return bAppExitWanted; } static bool bDoNotEnterHandler = false; // return TRUE = app exit wanted!!! // bool WinTalk_HandleMessages(void) { bool bAppExitWanted = false; if (!bDoNotEnterHandler) { bDoNotEnterHandler = true; if (!CommArea_IsIdle()) { CWaitCursor wait; byte *pbCommandData = NULL; int iCommandDataSize; LPCSTR psString; if ((psString = CommArea_IsCommandWaiting( &pbCommandData, &iCommandDataSize )) != NULL) { bAppExitWanted = HandleCommands(psString, pbCommandData, iCommandDataSize); } else if ((psString = CommArea_IsErrorWaiting()) != NULL) { assert(0); // i don't think we should ever get here, but just in case... ErrorBox(va("ModView: Other program reported an error:\n\n\"%s\"",psString)); CommArea_CommandClear(); } } bDoNotEnterHandler = false; } return bAppExitWanted; } // return is success/fail // bool WinTalk_IssueCommand( LPCSTR psCommand, byte *pbData, // optional extra command data (current max = 64k) int iDataSize, // sizeof above LPCSTR *ppsResultPassback, // optional result passback if expecting an answer string byte **ppbDataPassback, // optional data passback if expecting a data result int *piDataSizePassback // optional size of above if you need it supplying ) { bool bError = false; while (!CommArea_IsIdle()) { WinTalk_HandleMessages(); } bDoNotEnterHandler = false; { CommArea_IssueCommand(psCommand, pbData, iDataSize); // wait until command is acknowledged or has failed... (you may want a sanity check timeout?) // while (1) { LPCSTR psReply; if ((psReply = CommArea_IsAckWaiting(ppbDataPassback,piDataSizePassback)) != NULL) { if ( ppsResultPassback) *ppsResultPassback = psReply; bError = false; break; } if ((psReply = CommArea_IsErrorWaiting()) != NULL) { ErrorBox(va("Other program reported an error:\n\n\"%s\"",psReply)); bError = true; break; } Sleep(0); // needed to avoid hogging all CPU time :-) } // you MUST do this... // CommArea_CommandClear(); } bDoNotEnterHandler = false; return !bError; } ////////////////////// eof ////////////////