GRascm Posted August 4, 2011 Share Posted August 4, 2011 A year ago i posted a request for setPedAnimationProgress scripting function And there was no progress, it still has "new" status. I tried to implement it myself, but nothing work And i am asking for help now. This is original GTA opcode handler for 0x0614(0614: set_actor $PLAYER_ACTOR animation "GYM_BP_DOWN" progress_to $1822 // 0.0 to 1.0) opcode. With my(and not only my comments). .text:00491802 ; __linkproc__ opcode_0614 .text:00491802 @@opcode_0614: ; CODE XREF: _opcode_handler_15+37j .text:00491802 ; DATA XREF: .text:__linkproc__ opcode_tableo .text:00491802 234 push 1 ; set_actor %1d% animation %2h% progress_to %3d% // 0.0 to 1.0 .text:00491804 238 mov ecx, esi .text:00491806 238 call CScriptThread__getNumberParams .text:0049180B 234 mov ecx, _opcodeParameters .text:00491811 234 push ecx ; int .text:00491812 238 mov ecx, _PedPool .text:00491818 238 call ?atHandle@?$CPool@VCPed@@@@QAEPAVCVehicle@@I@Z ; CPed * CPool<CPed>::atHandle (u32 h); .text:0049181D 234 push 18h .text:0049181F 238 lea edx, [esp+238h+var_1E4] .text:00491823 238 push edx .text:00491824 23C mov ecx, esi .text:00491826 23C mov edi, eax .text:00491828 23C call _CScriptThread__getStringParam .text:0049182D 234 mov ecx, [edi+18h] .text:00491830 234 lea eax, [esp+234h+var_1E4] .text:00491834 234 push eax .text:00491835 238 push ecx ; This function is actually FUNC_RpAnimBlendClumpGetAssociation_str, stores pointer to CAnimBlendAssociationSAInterface in EAX .text:00491836 23C call sub_4D6870 .text:0049183B 23C add esp, 8 .text:0049183E 234 push 1 ; count .text:00491840 238 mov ecx, esi ;moving our pointer to EDI .text:00491842 238 mov edi, eax .text:00491844 238 call CScriptThread__getNumberParams ; if pointer is zero jump to return else continue running .text:00491849 234 test edi, edi .text:0049184B 234 jz loc_492203 ;Moving CAnimBlendHierarchySAInterface pointer from CAnimBlendAssociationSAInterface in EDX .text:00491851 234 mov edx, [edi+14h] ;It seems like loading fTotalTime field into FPU .text:00491854 234 fld dword ptr [edx+10h] ;I cant understand what this code do, but it is floating point multiplication i think (using the stack? o_O) .text:00491857 234 push ecx .text:00491858 238 fmul _opcodeParameters ;store in ecx pointer to CAnimBlendAssociationSAInterface .text:0049185E 238 mov ecx, edi .text:00491860 238 fstp [esp+238h+var_238] ;calling function that actually sets animation frame position, takes one float argument, also uses data from ECX(there stored our pointer to that time) .text:00491863 238 call sub_4CEA80 ; set animation progress .text:00491868 234 xor al, al .text:0049186A 234 jmp loc_492AAB the function beginng .text:004CEA80 arg_0 = dword ptr 4 ;taking the argument of the function .text:004CEA80 000 mov eax, [esp+arg_0] .text:004CEA84 000 fld [esp+arg_0] ;saving values, i think .text:004CEA88 000 push ebx .text:004CEA89 004 push esi moving our pointer to esi and working with it .text:004CEA8A 008 mov esi, ecx .text:004CEA8C 008 mov ecx, [esi+14h] .text:004CEA8F 008 mov [esi+20h], eax ;... continue I tried to add it to the MTA bool CStaticFunctionDefinitions::SetPedAnimationProgress ( CClientEntity& Entity, const char * szAnimName, float fProgress ) { RUN_CHILDREN SetPedAnimationProgress ( **iter, szAnimName, fProgress ); if ( IS_PED ( &Entity ) ) { CClientPed& Ped = static_cast < CClientPed& > ( Entity ); CAnimBlendAssociation* pA = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation ( Ped.GetClump (), szAnimName ); if ( pA ) { pA->SetCurrentTime ( fProgress ); } } return false; } and void CAnimBlendAssociationSA::SetCurrentTime ( float fTime ) { DWORD DwFunc = 0x4CEA80; // function that actually sets the progress float* fPointer = &fTime; //pointer to fTime, to pass it to function _asm { push ecx ; saving old ECX value mov ecx, m_pInterface ; moving "that" pointer to ECX, like the opcode handler push fPointer ; push the function argument call DwFunc ; call the function pop ecx ; and restore the ECX }; } But of course nothing works, and game crashes. May be anyone have any idea? What am i doing wrong? Link to comment
Maccer. Posted August 7, 2011 Share Posted August 7, 2011 SetPedAnimationProgress or 0x4CEA80 is possibly part of an undocumented virtual table and it is a THISCALL. It can either be something undocumented in IDA at 0x4CE940 or the interface at CAnimBlendAssociationSA The proper way to implement it AFAIK is DWORD DwFunc = 0x4CEA80; DWORD DwThisInterface = 0x8008135; // not a real pointer to any interface or vtbl _asm { // pushing and popping is already handled by the call or externally mov ecx, DwThisInterface push fTime // you're already pretty much pushing a reference in inline asm, not need to push a reference call dwFunc }; Link to comment
GRascm Posted August 9, 2011 Author Share Posted August 9, 2011 Yeah! Thank you for the tips, I made it! =) Not really great code, but it works. Here is the short demonstration of SetPedAnimationProgress function: And simple script, that i used to test animation progress: Progress = 0.5 function addAnim() setPedAnimation( getLocalPlayer(), "SMOKING", "M_SMKSTND_LOOP") end addEventHandler( "onClientPlayerSpawn", getLocalPlayer(), addAnim) function changeProgress(commandName, newProgress) Progress = newProgress / 100; end addCommandHandler("animprogress", changeProgress) function animRender() setPedAnimationProgress(getLocalPlayer(), "M_SMKSTND_LOOP", Progress) end addEventHandler("onClientRender", getRootElement(), animRender) And of cource a patch to MTA. http://pastebin.com/aC7tLWK3 I have implemented just a client setPedAnimationFunction, I hope someone will implement animation syncing, and i have a stupid question: /* Here must be something like float fNewTime = pA->GetInterface()->pAnimHierarchy->fTotalTime * fProgress; But only abstract classes avaliable here */ float fNewTime = *(float *)(*(DWORD *)( ((DWORD)(pA->GetInterface())) + 20) + 16) * fProgress; What to do with this? Link to comment
GRascm Posted August 14, 2011 Author Share Posted August 14, 2011 Fixed, i hope. I have done everething and have sent a patch to mantis. Link to comment
Arran Posted August 15, 2011 Share Posted August 15, 2011 Your patch was added: http://code.google.com/p/mtasa-blue/sou ... ail?r=3002 Now you have to document it on the wiki. Link to comment
GRascm Posted August 15, 2011 Author Share Posted August 15, 2011 I not very good in english, that's why i have documented it in english and russian both. Link to comment
MTA Team jhxp Posted August 15, 2011 MTA Team Share Posted August 15, 2011 Cool. Thank you for your contribution. Link to comment
Arran Posted August 15, 2011 Share Posted August 15, 2011 I not very good in english, that's why i have documented it in english and russian both. Your English documentation was good, totally understandable. Function will be useful for scripters, well done and I hope you do more! Well I'm guessing if you managed to make setPedAnimationProgress making other things wouldn't be as hard. Link to comment
Recommended Posts