Advertisement
expired6978

Hooks_ObScript

Dec 30th, 2016
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 36.87 KB | None | 0 0
  1. #include "Hooks_ObScript.h"
  2. #include "ObScript.h"
  3. #include "GameAPI.h"
  4. #include "GameReferences.h"
  5. #include "f4se_common/SafeWrite.h"
  6. #include "f4se_common/f4se_version.h"
  7.  
  8. // currently ForceRSXCrash, could also use ToggleESRAM and several others
  9. static ObScriptCommand * s_hijackedCommand = nullptr;
  10.  
  11. #ifdef _DEBUG
  12. static ObScriptCommand * s_testCommand = nullptr;
  13. #endif
  14.  
  15. void Hooks_ObScript_Init()
  16. {
  17.     // instead of hooking the entire classic scripting system, we're just hijacking some unused commands
  18.  
  19.     for(ObScriptCommand * iter = g_firstConsoleCommand; iter->opcode < kObScript_NumConsoleCommands; ++iter)
  20.     {
  21.         if(!strcmp(iter->longName, "ForceRSXCrash"))
  22.         {
  23.             s_hijackedCommand = iter;
  24. #ifndef _DEBUG
  25.             break;
  26. #endif
  27.         }
  28. #ifdef _DEBUG
  29.         if(!strcmp(iter->longName, "TestCode"))
  30.         {
  31.             s_testCommand = iter;
  32.         }
  33. #endif
  34.     }
  35.  
  36.     if(!s_hijackedCommand)
  37.     {
  38.         _ERROR("couldn't find obscript command to use");
  39.     }
  40. }
  41.  
  42. bool GetF4SEVersion_Execute(void * paramInfo, void * scriptData, TESObjectREFR * thisObj, void * containingObj, void * scriptObj, void * locals, double * result, void * opcodeOffsetPtr)
  43. {
  44.     _MESSAGE("GetF4SEVersion_Execute");
  45.  
  46.     Console_Print("F4SE version: %d.%d.%d, release idx %d, runtime %08X",
  47.         F4SE_VERSION_INTEGER, F4SE_VERSION_INTEGER_MINOR, F4SE_VERSION_INTEGER_BETA,
  48.         F4SE_VERSION_RELEASEIDX, RUNTIME_VERSION);
  49.     return true;
  50. }
  51.  
  52. #ifdef _DEBUG
  53. #include "f4se/GameRTTI.h"
  54. #include "f4se/GameObjects.h"
  55. #include "f4se/GameData.h"
  56. #include "f4se/GameMenus.h"
  57. #include "f4se/GameMessages.h"
  58. #include "f4se/BSGeometry.h"
  59. #include "f4se/NiProperties.h"
  60. #include "f4se/NiMaterials.h"
  61. #include "f4se/NiNodes.h"
  62. #include "f4se/NiRTTI.h"
  63. #include "f4se/NiExtraData.h"
  64. #include "f4se/GameExtraData.h"
  65. #include "f4se/GameThreads.h"
  66. #include "f4se/Hooks_Threads.h"
  67. #include "f4se/BSModelDB.h"
  68. #include <functional>
  69. #include "f4se/BSGraphics.h"
  70. #include "f4se/NiTextures.h"
  71. #include "f4se/PapyrusEvents.h"
  72.  
  73. RelocAddr <uintptr_t> GetActorBaseHeadData_Start(0x00687940 + 0xCF);
  74. RelocAddr <uintptr_t> GetMorphGroups_Start(0x00687940 + 0x390);
  75. RelocAddr <uintptr_t> StaticTextureIndexed_Ctor_Start(0x00687940 + 0xD38);
  76.  
  77. RelocPtr<UInt32> g_faceGenTextureWidth(0x036F0AD0);
  78. RelocPtr<UInt32> g_faceGenTextureHeight(0x036F0AD4);
  79.  
  80. typedef void (* _InitializeSharedTarget)(BSRenderTargetManager * targetManager, UInt32 type, BSRenderTargetManager::SharedTargetInfo * targetInfo, UInt8 unk1);
  81. RelocAddr <_InitializeSharedTarget> InitializeSharedTarget(0x01D054F0);
  82. _InitializeSharedTarget InitializeSharedTarget_Original = nullptr;
  83.  
  84. void InitializeSharedTarget_Hook(BSRenderTargetManager * targetManager, UInt32 type, BSRenderTargetManager::SharedTargetInfo * targetInfo, UInt8 unk1)
  85. {
  86.     switch(type)
  87.     {
  88.     case 16:
  89.     case 17:
  90.     case 18:
  91.         targetInfo->width = 4096;
  92.         targetInfo->height = 4096;
  93.         break;
  94.     }
  95.     InitializeSharedTarget_Original(targetManager, type, targetInfo, unk1);
  96. }
  97.  
  98. #include <mutex>
  99. #include "f4se/GameObjects.h"
  100. #include "f4se_common/Relocation.h"
  101. #include "f4se_common/BranchTrampoline.h"
  102. #include "f4se_common/SafeWrite.h"
  103. #include "xbyak/xbyak.h"
  104. #include "common/ICriticalSection.h"
  105.  
  106. class F4SECharGen
  107. {
  108. public:
  109.     void SetBaseTintTextureOverride(BGSTextureSet * textureSet)
  110.     {
  111.         m_faceTextureOverride.faceTextures = textureSet;
  112.     }
  113.  
  114.     void LockBaseTextureOverride()
  115.     {
  116.         m_cs.Enter();
  117.     }
  118.  
  119.     void ReleaseBaseTextureOverride()
  120.     {
  121.         m_cs.Leave();
  122.     }
  123.  
  124.     TESNPC::HeadData * ProcessHeadData(TESNPC * npc)
  125.     {
  126.         IScopedCriticalSection locker(&m_cs);
  127.         if(m_faceTextureOverride.faceTextures) {
  128.             return &m_faceTextureOverride;
  129.         }
  130.  
  131.         return npc->headData;
  132.     }
  133.  
  134.     tArray<CharacterCreation::MorphGroup*> * ProcessMorphGroups(CharacterCreation::CharGenData * chargenData)
  135.     {
  136.         IScopedCriticalSection locker(&m_cs);
  137.         if(m_faceTextureOverride.faceTextures) {
  138.             return nullptr;
  139.         }
  140.  
  141.         return chargenData->morphGroups;
  142.     }
  143.  
  144.     TESNPC::HeadData m_faceTextureOverride;
  145.     ICriticalSection m_cs;
  146. };
  147.  
  148. F4SECharGen g_charGen;
  149.  
  150. TESNPC::HeadData * GetActorBaseHeadData_Hook(TESNPC * npc)
  151. {
  152.     return g_charGen.ProcessHeadData(npc);
  153. }
  154.  
  155.  
  156. BSTextureArray::StaticTextureIndexed* StaticTextureIndexed_ctor_Hook(BSTextureArray::StaticTextureIndexed* _this, UInt32 unk1, int unk2, bool unk3)
  157. {
  158.     BSTextureArray::StaticTextureIndexed* ret = CALL_MEMBER_FN(_this, ctor)(unk1, unk2, unk3);
  159.     //ret->unk18 = 4096;
  160.     return ret;
  161. }
  162.  
  163. tArray<CharacterCreation::MorphGroup*> * GetMorphGroups_Hook(CharacterCreation::CharGenData * chargenData)
  164. {
  165.     return g_charGen.ProcessMorphGroups(chargenData);
  166. }
  167.  
  168. ObScriptCommand * GetCommandByOpcode(UInt16 opcode)
  169. {
  170.     for(ObScriptCommand * iter = g_firstConsoleCommand; iter->opcode < kObScript_NumConsoleCommands; ++iter)
  171.     {
  172.         if(iter->opcode == opcode)
  173.             return iter;
  174.     }
  175.  
  176.     return nullptr;
  177. }
  178.  
  179. void DumpNodeChildren(NiAVObject * node)
  180. {
  181.     _MESSAGE("{%s} {%s} {%X} {Flags %016I64X}", node->GetRTTI()->name, node->m_name.c_str(), node, node->flags);
  182.     if(node->m_extraData) {
  183.         gLog.Indent();
  184.         for(UInt16 i = 0; i < node->m_extraData->count; i++) {
  185.             _MESSAGE("{%s} {%s} {%X}", node->m_extraData->entries[i]->GetRTTI()->name, node->m_extraData->entries[i]->m_name.c_str(), node);
  186.         }
  187.         gLog.Outdent();
  188.     }
  189.     //DumpClass(node);
  190.     NiNode * niNode = node->GetAsNiNode();
  191.     if(niNode && niNode->m_children.m_emptyRunStart > 0)
  192.     {
  193.         gLog.Indent();
  194.         for(int i = 0; i < niNode->m_children.m_emptyRunStart; i++)
  195.         {
  196.             NiAVObject * object = niNode->m_children.m_data[i];
  197.             if(object) {
  198.                 BSTriShape * trishape = object->GetAsBSTriShape();
  199.                 BSDynamicTriShape * dynamicShape = object->GetAsBSDynamicTriShape();
  200.                 if(trishape || dynamicShape) {
  201.                     _MESSAGE("{%s} {%s} {%X} {Vertices %d} {Flags %016I64X}", trishape->GetRTTI()->name, trishape->m_name.c_str(), trishape, trishape->numVertices, trishape->flags);
  202.                     if(object->m_extraData) {
  203.                         gLog.Indent();
  204.                         for(UInt16 i = 0; i < object->m_extraData->count; i++) {
  205.                             _MESSAGE("{%s} {%s} {%X} {Flags %016I64X}", object->m_extraData->entries[i]->GetRTTI()->name, object->m_extraData->entries[i]->m_name.c_str(), object, object->flags);
  206.                         }
  207.                         gLog.Outdent();
  208.                     }                  
  209.                 } else {
  210.                     DumpNodeChildren(object);
  211.                 }
  212.             }
  213.         }
  214.         gLog.Outdent();
  215.     }
  216. }
  217.  
  218. bool VisitObjects(NiAVObject * parent, std::function<bool(NiAVObject*)> functor)
  219. {
  220.     if (functor(parent))
  221.         return true;
  222.  
  223.     NiPointer<NiNode> node(parent->GetAsNiNode());
  224.     if(node) {
  225.         for(UInt32 i = 0; i < node->m_children.m_emptyRunStart; i++) {
  226.             NiPointer<NiAVObject> object(node->m_children.m_data[i]);
  227.             if(object) {
  228.                 if (VisitObjects(object, functor))
  229.                     return true;
  230.             }
  231.         }
  232.     }
  233.  
  234.     return false;
  235. }
  236.  
  237. #include "GameThreads.h"
  238.  
  239. class SomeTask : public ITaskDelegate
  240. {
  241. public:
  242.     virtual void Run() override
  243.     {
  244.         IMenu * pMenu = (*g_ui)->GetMenu(&BSFixedString("HUDMenu"));
  245.         if(pMenu)
  246.         {
  247.             DumpClass(pMenu, sizeof(HUDMenu)>>3);
  248.             GFxMovieRoot * movieRoot = pMenu->movie->movieRoot;
  249.             GFxValue::DisplayInfo dp;
  250.             pMenu->stage.GetDisplayInfo(&dp);
  251.             dp.SetAlpha(50.0f);
  252.             pMenu->stage.SetDisplayInfo(&dp);
  253.         }
  254.     }
  255. };
  256.  
  257. class CombatSink : public BSTEventSink<TESCombatEvent>
  258. {
  259. public:
  260.     virtual EventResult ReceiveEvent(TESCombatEvent * evn, void * dispatcher) override
  261.     {
  262.         DumpClass(evn, sizeof(TESCombatEvent)/8);
  263.         return kEvent_Continue;
  264.     }
  265. };
  266.  
  267. CombatSink combatSink;
  268.  
  269.  
  270. #include "d3d11.h"
  271.  
  272. bool F4SETestCode_Execute(void * paramInfo, void * scriptData, TESObjectREFR * thisObj, void * containingObj, void * scriptObj, void * locals, double * result, void * opcodeOffsetPtr)
  273. {
  274.     /*for(UInt32 i = 0; i < (*g_dataHandler)->arrHDPT.count; i++)
  275.     {
  276.         BGSHeadPart * headPart = (*g_dataHandler)->arrHDPT[i];
  277.         _MESSAGE("Part: %s", headPart->partName.data ? headPart->partName.data->Get<char>() : "");
  278.         DumpClass(headPart, sizeof(BGSHeadPart)/8);
  279.     }*/
  280.  
  281.     //TaskInterface::AddUITask(new SomeTask);
  282.  
  283.    
  284.  
  285.     //GetEventDispatcher<TESCombatEvent>()->AddEventSink(&combatSink);
  286.     //pCombatEventDispatcher->RemoveEventSink(&combatSink);
  287.     //return false;
  288.  
  289.     /*
  290.     if(!thisObj)
  291.         return true;
  292.  
  293.     (*g_gameVM)->m_virtualMachine->m_typeNames.Dump();
  294.  
  295.     VMArray<VMVariable> vmData;
  296.     VMVariable forceOpen;
  297.     bool bForce = true;
  298.     forceOpen.Set(&bForce);
  299.     vmData.Push(&forceOpen);
  300.     CallFunctionNoWait<TESObjectREFR>(thisObj, "OpenInventory", vmData);*/
  301.  
  302.     /*
  303.     auto pTints = (*g_player)->tints;
  304.     _MESSAGE("NPC Tint Entries: %d", pTints->count);
  305.  
  306.     CharacterCreation::CharGenData * chargenData = nullptr;
  307.     TESNPC * actorBase = DYNAMIC_CAST(thisObj->baseForm, TESForm, TESNPC);
  308.     if(actorBase) {
  309.         TESRace * race = actorBase->race.race;
  310.         UInt8 gender = CALL_MEMBER_FN(actorBase, GetSex)();
  311.         chargenData = race->chargenData[gender];
  312.     }
  313.  
  314.     for(UInt32 i = 0; i < pTints->count; i++)
  315.     {
  316.         BGSCharacterTint::Entry * entry;
  317.         pTints->GetNthItem(i, entry);
  318.  
  319.         if(!entry->templateEntry && chargenData) {
  320.             entry->templateEntry = chargenData->GetTemplateByIndex(entry->tintIndex);
  321.         }
  322.  
  323.         _MESSAGE("Entry: Index: %08X, percent: %d", entry->tintIndex, entry->percent);
  324.         switch(entry->GetType())
  325.         {
  326.         case BGSCharacterTint::Entry::kTypeMask:
  327.             {
  328.                 gLog.Indent();
  329.                 BGSCharacterTint::Template::Mask * templateMask = static_cast<BGSCharacterTint::Template::Mask *>(entry->templateEntry);
  330.                 if(templateMask)
  331.                 {
  332.                     _MESSAGE("Mask: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOp: %08X, unk2C: %08X", templateMask->templateIndex, templateMask->name.data ? templateMask->name.data->Get<char>() : "", templateMask->slot, templateMask->flags, templateMask->unk1F, templateMask->blendOp, templateMask->unk2C);
  333.                 }
  334.                 gLog.Outdent();
  335.             }
  336.             break;
  337.         case BGSCharacterTint::Entry::kTypeTexture:
  338.             {
  339.                 gLog.Indent();
  340.                 BGSCharacterTint::Template::TextureSet * templateTexture = static_cast<BGSCharacterTint::Template::TextureSet *>(entry->templateEntry);
  341.                 if(templateTexture)
  342.                 {
  343.                     _MESSAGE("Texture: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOP: %08X, default: %f", templateTexture->templateIndex, templateTexture->name.data ? templateTexture->name.data->Get<char>() : "", templateTexture->slot, templateTexture->flags, templateTexture->unk1F, templateTexture->blendOp, templateTexture->defaultValue);
  344.                     gLog.Indent();
  345.                     _MESSAGE("Diffuse: %s", templateTexture->diffuse.data ? templateTexture->diffuse.data->Get<char>() : "Empty");
  346.                     _MESSAGE("Normal: %s", templateTexture->specular.data ? templateTexture->specular.data->Get<char>() : "Empty");
  347.                     _MESSAGE("Specular: %s", templateTexture->normal.data ? templateTexture->normal.data->Get<char>() : "Empty");
  348.                     gLog.Outdent();
  349.                 }
  350.                 gLog.Outdent();
  351.             }
  352.             break;
  353.         case BGSCharacterTint::Entry::kTypePalette:
  354.             {
  355.                 gLog.Indent();
  356.                 BGSCharacterTint::PaletteEntry* paletteEntry = static_cast<BGSCharacterTint::PaletteEntry*>(entry);
  357.                 _MESSAGE("Palette: color: %08X, colorID: %04X", paletteEntry->color, paletteEntry->colorID);
  358.  
  359.                 BGSCharacterTint::Template::Palette * templatePalette = static_cast<BGSCharacterTint::Template::Palette *>(entry->templateEntry);
  360.                 if(templatePalette)
  361.                 {
  362.  
  363.                     _MESSAGE("Mask: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, unk28: %08X, unk2C: %08X", templatePalette->templateIndex, templatePalette->name.data ? templatePalette->name.data->Get<char>() : "", templatePalette->slot, templatePalette->flags, templatePalette->unk1F, templatePalette->unk28, templatePalette->unk2C);
  364.                     gLog.Indent();
  365.                     for(UInt32 k = 0; k < templatePalette->colors.count; k++)
  366.                     {
  367.                         BGSCharacterTint::Template::Palette::ColorData colorData;
  368.                         templatePalette->colors.GetNthItem(k, colorData);
  369.                         _MESSAGE("Color: Name: %s FormID: %08X, Color: %08X, alpha: %f, blendOp: %08X, colorID: %04X, unk12: %04X, unk14: %04X", colorData.colorForm->fullName.name.data ? colorData.colorForm->fullName.name.data->Get<char>() : "", colorData.colorForm->formID, colorData.colorForm->color.rgb, colorData.alpha, colorData.blendOp, colorData.colorID, colorData.unk12, colorData.unk14);
  370.                     }
  371.                     gLog.Outdent();
  372.                 }
  373.                 gLog.Outdent();
  374.             }
  375.             break;
  376.  
  377.         }
  378.  
  379.     }
  380.  
  381.     return true;*/
  382.  
  383.     TESNPC * actorBase = DYNAMIC_CAST(thisObj->baseForm, TESForm, TESNPC);
  384.     if(actorBase) {
  385.         TESRace * race = actorBase->race.race;
  386.         UInt8 gender = CALL_MEMBER_FN(actorBase, GetSex)();
  387.         auto chargenData = race->chargenData[gender];
  388.         NiNode * root = thisObj->GetObjectRootNode();
  389.         VisitObjects(root, [&](NiAVObject* object) {
  390.             BSTriShape * trishape = object->GetAsBSTriShape();
  391.             if(trishape) {
  392.                 BSLightingShaderProperty * lightingShader = ni_cast(trishape->shaderProperty, BSLightingShaderProperty);
  393.                 if(lightingShader) {
  394.                     BSLightingShaderMaterialBase * material = static_cast<BSLightingShaderMaterialBase *>(lightingShader->shaderMaterial);
  395.                     if(material->GetType() == BSLightingShaderMaterialBase::kType_SkinTint) {
  396.                         BSLightingShaderMaterialFace * faceMaterial = static_cast<BSLightingShaderMaterialFace*>(CreateShaderMaterialByType(BSLightingShaderMaterialBase::kType_Face));
  397.                         CALL_MEMBER_FN(faceMaterial, Copy)(material);
  398.                         CALL_MEMBER_FN(lightingShader, SetFlag)(21, false); // Turn off SkinTint
  399.                         CALL_MEMBER_FN(lightingShader, SetFlag)(9, true); // Turn on FaceTint
  400.  
  401.                         //faceMaterial->baseDiffuse = material->spDiffuseTexture;
  402.  
  403.                         tArray<BGSCharacterTint::Entry*> tempTints;
  404.                         tArray<BGSCharacterTint::Entry*> * previousTints = nullptr;
  405.                         if(thisObj == (*g_player))
  406.                             previousTints = (*g_player)->tints;
  407.                         else
  408.                             previousTints = actorBase->tints;
  409.                         /*if(thisObj == (*g_player))
  410.                             CopyCharacterTints(&tempTints, (*g_player)->tints);
  411.                         else
  412.                             CopyCharacterTints(&tempTints, actorBase->tints);
  413.  
  414.                         for(int i = 0; i < tempTints.count; i++)
  415.                         {
  416.                             BGSCharacterTint::Entry * entry;
  417.                             tempTints.GetNthItem(i, entry);
  418.                             auto tintTemplate = chargenData->GetTemplateByIndex(entry->tintIndex);
  419.                             entry->templateEntry = tintTemplate;
  420.                         }*/
  421.  
  422.  
  423.                         /*BGSCharacterTint::TextureSetEntry* pTextureSet = (BGSCharacterTint::TextureSetEntry*)CreateCharacterTintEntry((3587L << 16) | BGSCharacterTint::Entry::kTypeTexture);
  424.                         pTextureSet->templateEntry = chargenData->GetTemplateByIndex(3587);
  425.                         pTextureSet->percent = 100;
  426.                         tempTints.Push(pTextureSet);*/
  427.  
  428.                         BGSCharacterTint::PaletteEntry* pSkinReference = nullptr;
  429.                         BGSCharacterTint::Template::Palette * pSkinTemplate = nullptr;
  430.                         for(int i = 0; i < previousTints->count; i++)
  431.                         {
  432.                             BGSCharacterTint::Entry* tintEntry;
  433.                             previousTints->GetNthItem(i, tintEntry);
  434.  
  435.                             if(tintEntry->tintIndex == 0x490)
  436.                             {
  437.                                 pSkinReference = static_cast<BGSCharacterTint::PaletteEntry*>(tintEntry);
  438.                                 pSkinTemplate = static_cast<BGSCharacterTint::Template::Palette*>(chargenData->GetTemplateByIndex(tintEntry->tintIndex));
  439.                                 break;
  440.                             }
  441.                         }
  442.  
  443.                         BGSCharacterTint::Template::Palette * pSkinToneTemplate = BGSCharacterTint::Template::Palette::Create();
  444.                         pSkinToneTemplate->templateIndex = 3587;
  445.                         pSkinToneTemplate->texture = BSFixedString("Actors\\Character\\Character Assets\\TintMasks\\BodySkinTone.dds");
  446.                         pSkinToneTemplate->slot = BGSCharacterTint::Template::Entry::kSlotSkinTone;
  447.                         for(int i = 0; i < pSkinTemplate->colors.count; i++)
  448.                         {
  449.                             BGSCharacterTint::Template::Palette::ColorData colorData;
  450.                             pSkinTemplate->colors.GetNthItem(i, colorData);
  451.                             pSkinToneTemplate->colors.Push(colorData);
  452.                         }
  453.  
  454.                         BGSCharacterTint::PaletteEntry* pSkinTone = (BGSCharacterTint::PaletteEntry*)CreateCharacterTintEntry((3587L << 16) | BGSCharacterTint::Entry::kTypePalette);
  455.                         pSkinTone->color = pSkinReference->color;//0x00CBD3E7;
  456.                         pSkinTone->colorID = pSkinReference->colorID;
  457.                         pSkinTone->percent = pSkinReference->percent;
  458.                         pSkinTone->templateEntry = pSkinToneTemplate;
  459.                         tempTints.Push(pSkinTone);
  460.  
  461.                        
  462.                         /*
  463.                         auto pTints = &tempTints;
  464.                         _MESSAGE("NPC Tint Entries: %d", pTints->count);
  465.  
  466.                         for(UInt32 i = 0; i < pTints->count; i++)
  467.                         {
  468.                             BGSCharacterTint::Entry * entry;
  469.                             pTints->GetNthItem(i, entry);
  470.  
  471.                             _MESSAGE("Entry: Index: %08X, percent: %d", entry->tintIndex, entry->percent);
  472.                             switch(entry->GetType())
  473.                             {
  474.                             case BGSCharacterTint::Entry::kTypeMask:
  475.                                 {
  476.                                     gLog.Indent();
  477.                                     BGSCharacterTint::Template::Mask * templateMask = static_cast<BGSCharacterTint::Template::Mask *>(entry->templateEntry);
  478.                                     if(templateMask)
  479.                                     {
  480.                                         _MESSAGE("Mask: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOp: %08X, unk2C: %08X", templateMask->templateIndex, templateMask->name.data ? templateMask->name.data->Get<char>() : "", templateMask->slot, templateMask->flags, templateMask->unk1F, templateMask->blendOp, templateMask->unk2C);
  481.                                     }
  482.                                     gLog.Outdent();
  483.                                 }
  484.                                 break;
  485.                             case BGSCharacterTint::Entry::kTypeTexture:
  486.                                 {
  487.                                     gLog.Indent();
  488.                                     BGSCharacterTint::Template::TextureSet * templateTexture = static_cast<BGSCharacterTint::Template::TextureSet *>(entry->templateEntry);
  489.                                     if(templateTexture)
  490.                                     {
  491.                                         _MESSAGE("Texture: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOP: %08X, default: %f", templateTexture->templateIndex, templateTexture->name.data ? templateTexture->name.data->Get<char>() : "", templateTexture->slot, templateTexture->flags, templateTexture->unk1F, templateTexture->blendOp, templateTexture->defaultValue);
  492.                                         gLog.Indent();
  493.                                         _MESSAGE("Diffuse: %s", templateTexture->diffuse.data ? templateTexture->diffuse.data->Get<char>() : "Empty");
  494.                                         _MESSAGE("Normal: %s", templateTexture->specular.data ? templateTexture->specular.data->Get<char>() : "Empty");
  495.                                         _MESSAGE("Specular: %s", templateTexture->normal.data ? templateTexture->normal.data->Get<char>() : "Empty");
  496.                                         gLog.Outdent();
  497.                                     }
  498.                                     gLog.Outdent();
  499.                                 }
  500.                                 break;
  501.                             case BGSCharacterTint::Entry::kTypePalette:
  502.                                 {
  503.                                     gLog.Indent();
  504.                                     BGSCharacterTint::PaletteEntry* paletteEntry = static_cast<BGSCharacterTint::PaletteEntry*>(entry);
  505.                                     _MESSAGE("Palette: color: %08X, colorID: %04X", paletteEntry->color, paletteEntry->colorID);
  506.  
  507.                                     BGSCharacterTint::Template::Palette * templatePalette = static_cast<BGSCharacterTint::Template::Palette *>(entry->templateEntry);
  508.                                     if(templatePalette)
  509.                                     {
  510.  
  511.                                         _MESSAGE("Mask: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, unk28: %08X, unk2C: %08X", templatePalette->templateIndex, templatePalette->name.data ? templatePalette->name.data->Get<char>() : "", templatePalette->slot, templatePalette->flags, templatePalette->unk1F, templatePalette->unk28, templatePalette->unk2C);
  512.                                         gLog.Indent();
  513.                                         for(UInt32 k = 0; k < templatePalette->colors.count; k++)
  514.                                         {
  515.                                             BGSCharacterTint::Template::Palette::ColorData colorData;
  516.                                             templatePalette->colors.GetNthItem(k, colorData);
  517.                                             _MESSAGE("Color: Name: %s FormID: %08X, Color: %08X, alpha: %f, blendOp: %08X, colorID: %04X, unk12: %04X, unk14: %04X", colorData.colorForm->fullName.name.data ? colorData.colorForm->fullName.name.data->Get<char>() : "", colorData.colorForm->formID, colorData.colorForm->color.rgb, colorData.alpha, colorData.blendOp, colorData.colorID, colorData.unk12, colorData.unk14);
  518.                                         }
  519.                                         gLog.Outdent();
  520.                                     }
  521.                                     gLog.Outdent();
  522.                                 }
  523.                                 break;
  524.  
  525.                             }
  526.  
  527.                         }*/
  528.                        
  529.                         //FillTintTemplates(tempTints, chargenData);
  530.                         auto pFaceGenManager = (*g_faceGenManager);
  531.  
  532.                         faceMaterial->baseDiffuse = material->spDiffuseTexture;
  533.  
  534.                         g_charGen.LockBaseTextureOverride();
  535.                         g_charGen.SetBaseTintTextureOverride((BGSTextureSet *)LookupFormByID(0xF7E66));
  536.                         CreateMergeTintTextures(actorBase, &tempTints, nullptr, 0);
  537.                         g_charGen.SetBaseTintTextureOverride(nullptr);
  538.                         g_charGen.ReleaseBaseTextureOverride();
  539.  
  540.                         CALL_MEMBER_FN(g_renderTargetManager, LockTextureType)(16);
  541.                         CALL_MEMBER_FN(g_renderTargetManager, LockTextureType)(17);
  542.                         CALL_MEMBER_FN(g_renderTargetManager, LockTextureType)(18);
  543.  
  544.                         NiPointer<NiTexture> diffuse = CreateTexture("FaceCustomizationDiffuse", 1);
  545.                         diffuse->rendererData = CALL_MEMBER_FN(g_renderTargetManager, GetRenderData)(16, 1, 1, 0);
  546.                         faceMaterial->spDiffuseTexture = diffuse;
  547.  
  548.                         D3D11_TEXTURE2D_DESC pDesc;
  549.                         ((ID3D11Texture2D *)diffuse->rendererData->resource)->GetDesc(&pDesc);
  550.                        
  551.                         NiPointer<NiTexture> normal = CreateTexture("FaceCustomizationNormals", 0);
  552.                         normal->rendererData = CALL_MEMBER_FN(g_renderTargetManager, GetRenderData)(17, 1, 1, 0);
  553.                         faceMaterial->spNormalTexture = normal;
  554.                         //faceMaterial->spNormalTexture = material->spNormalTexture;
  555.  
  556.                         ((ID3D11Texture2D *)normal->rendererData->resource)->GetDesc(&pDesc);
  557.  
  558.                         NiPointer<NiTexture> spec = CreateTexture("FaceCustomizationSmoothSpec", 0);
  559.                         spec->rendererData = CALL_MEMBER_FN(g_renderTargetManager, GetRenderData)(18, 1, 1, 0);
  560.                         faceMaterial->spSmoothnessSpecMaskTexture = spec;
  561.                         //faceMaterial->spSmoothnessSpecMaskTexture = material->spSmoothnessSpecMaskTexture;
  562.  
  563.                         ((ID3D11Texture2D *)spec->rendererData->resource)->GetDesc(&pDesc);
  564.  
  565.                         CALL_MEMBER_FN(g_renderTargetManager, ReleaseTextureType)(16);
  566.                         CALL_MEMBER_FN(g_renderTargetManager, ReleaseTextureType)(17);
  567.                         CALL_MEMBER_FN(g_renderTargetManager, ReleaseTextureType)(18);
  568.  
  569.                         CALL_MEMBER_FN(lightingShader, SetMaterial)(faceMaterial, true);
  570.                         CALL_MEMBER_FN(lightingShader, MakeValidForRendering)(trishape);
  571.                     }
  572.                 }
  573.             }
  574.             return false;
  575.         });
  576.     }
  577.  
  578.     return true;
  579.  
  580.     if(!thisObj)
  581.         return true;
  582.  
  583.     /*PlayerCharacter * pc2 = DYNAMIC_CAST(thisObj, TESForm, PlayerCharacter);
  584.     if(pc2) {
  585.         auto equipData = pc2->equipData;
  586.         if(equipData) {
  587.             for(int i = 0; i < ActorEquipData::kMaxSlots; i++)
  588.             {
  589.                 if(equipData->slots[i].item) {
  590.                     DumpClass(equipData->slots[i].item, max(sizeof(TESObjectARMO) >> 3, sizeof(TESObjectWEAP) >> 3));
  591.                 }
  592.             }
  593.         }
  594.     }*/
  595.  
  596.     DumpNodeChildren(thisObj->GetObjectRootNode());
  597.     return true;
  598.  
  599.     PlayerCharacter * pc = DYNAMIC_CAST(thisObj, TESForm, PlayerCharacter);
  600.     if(0)
  601.     {
  602.         for(int i = 0; i < ActorEquipData::kMaxSlots; i++)
  603.         {
  604.             DumpClass(&pc->equipData->slots[i], sizeof(ActorEquipData::SlotData)/8);
  605.             if(pc->equipData->slots[i].instanceData)
  606.             {
  607.                 TBO_InstanceData * instanceData = pc->equipData->slots[i].instanceData;
  608.                 if(Runtime_DynamicCast(instanceData, RTTI_TBO_InstanceData, RTTI_TESObjectWEAP__InstanceData))
  609.                 {
  610.                     DumpClass(instanceData, sizeof(TESObjectWEAP::InstanceData)/8 + 10);
  611.                 }
  612.                 if(Runtime_DynamicCast(instanceData, RTTI_TBO_InstanceData, RTTI_TESObjectARMO__InstanceData))
  613.                 {
  614.                     DumpClass(instanceData, sizeof(TESObjectARMO::InstanceData)/8 + 10);
  615.                 }
  616.             }
  617.             BGSObjectInstanceExtra * extraData = pc->equipData->slots[i].extraData;
  618.             if(extraData)
  619.             {
  620.                 if(extraData->data)
  621.                 {
  622.                     for(int i = 0; i < extraData->data->blockSize / sizeof(BGSObjectInstanceExtra::Data::Form); i++)
  623.                     {
  624.                         TESForm * form = LookupFormByID(extraData->data->forms[i].formId);
  625.                         DumpClass(form, 1);
  626.                     }
  627.                 }
  628.             }
  629.         }
  630.     }
  631.  
  632.  
  633.     TESNPC * npc = DYNAMIC_CAST(thisObj->baseForm, TESForm, TESNPC);
  634.     if(0)
  635.     {
  636.         TESRace * race = npc->race.race;
  637.         UInt8 gender = CALL_MEMBER_FN(npc, GetSex)();
  638.  
  639.         CharacterCreation::CharGenData * chargen = race->chargenData[gender];
  640.         TESRace::BoneScaleMap * boneScaleMap = race->boneScaleMap[gender];
  641.  
  642.         auto tints = chargen->tintData;
  643.         _MESSAGE("TintData Categories: %d", tints->count);
  644.         for(UInt32 i = 0; i < tints->count; i++)
  645.         {
  646.             CharacterCreation::TintData * tintData;
  647.             tints->GetNthItem(i, tintData);
  648.  
  649.             _MESSAGE("TintData Category: %s, Type: %08X, Count: %d", tintData->category.data ? tintData->category.data->Get<char>() : "", tintData->type, tintData->entry.count);
  650.             gLog.Indent();
  651.             for(UInt32 k = 0; k < tintData->entry.count; k++)
  652.             {
  653.                 BGSCharacterTint::Template::Entry * templateEntry;
  654.                 tintData->entry.GetNthItem(k, templateEntry);
  655.  
  656.                 BGSCharacterTint::Template::Mask * pMask = (BGSCharacterTint::Template::Mask *)Runtime_DynamicCast(templateEntry, RTTI_BGSCharacterTint__Template__Entry, RTTI_BGSCharacterTint__Template__Mask);
  657.                 if(pMask)
  658.                 {
  659.                     _MESSAGE("Mask: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOp: %08X, unk2C: %08X", pMask->templateIndex, pMask->name.data ? pMask->name.data->Get<char>() : "", pMask->slot, pMask->flags, pMask->unk1F, pMask->blendOp, pMask->unk2C);
  660.                 }
  661.                 BGSCharacterTint::Template::Palette * pPalette = (BGSCharacterTint::Template::Palette *)Runtime_DynamicCast(templateEntry, RTTI_BGSCharacterTint__Template__Entry, RTTI_BGSCharacterTint__Template__Palette);
  662.                 if(pPalette)
  663.                 {
  664.                     _MESSAGE("Palette: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, unk28: %08X, unk2C: %08X", pPalette->templateIndex, pPalette->name.data ? pPalette->name.data->Get<char>() : "", pPalette->slot, pPalette->flags, pPalette->unk1F, pPalette->unk28, pPalette->unk2C);
  665.                     gLog.Indent();
  666.                     for(UInt32 k = 0; k < pPalette->colors.count; k++)
  667.                     {
  668.                         BGSCharacterTint::Template::Palette::ColorData colorData;
  669.                         pPalette->colors.GetNthItem(k, colorData);
  670.                         _MESSAGE("Color: Name: %s FormID: %08X, Color: %08X, alpha: %f, blendOp: %08X, colorID: %04X, unk12: %04X, unk14: %04X", colorData.colorForm->fullName.name.data ? colorData.colorForm->fullName.name.data->Get<char>() : "", colorData.colorForm->formID, colorData.colorForm->color.rgb, colorData.alpha, colorData.blendOp, colorData.colorID, colorData.unk12, colorData.unk14);
  671.                     }
  672.                     gLog.Outdent();
  673.                 }
  674.                 BGSCharacterTint::Template::TextureSet * pTS = (BGSCharacterTint::Template::TextureSet *)Runtime_DynamicCast(templateEntry, RTTI_BGSCharacterTint__Template__Entry, RTTI_BGSCharacterTint__Template__TextureSet);
  675.                 if(pTS)
  676.                 {
  677.                     _MESSAGE("TextureSet: Index: %08X, Name: %s, slot: %d, flags: %d, unk1F: %d, blendOp: %08X, defaultValue: %f", pTS->templateIndex, pTS->name.data ? pTS->name.data->Get<char>() : "", pTS->slot, pTS->flags, pTS->unk1F, pTS->blendOp, pTS->defaultValue);
  678.                     gLog.Indent();
  679.                     _MESSAGE("Diffuse: %s", pTS->diffuse.data ? pTS->diffuse.data->Get<char>() : "Empty");
  680.                     _MESSAGE("Normal: %s", pTS->specular.data ? pTS->specular.data->Get<char>() : "Empty");
  681.                     _MESSAGE("Specular: %s", pTS->normal.data ? pTS->normal.data->Get<char>() : "Empty");
  682.                     gLog.Outdent();
  683.                 }
  684.             }
  685.             gLog.Outdent();
  686.         }
  687.  
  688.         /*auto morphs = chargen->faceMorphs;
  689.         _MESSAGE("FaceMorphRegions: %d", morphs->count);
  690.         for(UInt32 i = 0; i < morphs->count; i++)
  691.         {
  692.             CharacterCreation::FaceMorphRegion * region;
  693.             morphs->GetNthItem(i, region);
  694.  
  695.             _MESSAGE("MorphRegion Index: %08X, Name: %s", region->index, region->name.data ? region->name.data->Get<char>() : "");
  696.             //gLog.Indent();
  697.             //region->dataSet.Dump();
  698.             //gLog.Outdent();
  699.         }
  700.  
  701.         auto morphGroups = chargen->morphGroups;
  702.         _MESSAGE("MorphGroups: %d", morphGroups->count);
  703.         for(UInt32 i = 0; i < morphGroups->count; i++)
  704.         {
  705.             CharacterCreation::MorphGroup * morphGroup;
  706.             morphGroups->GetNthItem(i, morphGroup);
  707.  
  708.             _MESSAGE("MorphGroup Key: %08X, Name: %s, Count: %d", morphGroup->key, morphGroup->name.data ? morphGroup->name.data->Get<char>() : "", morphGroup->presets.count);
  709.             gLog.Indent();
  710.             for(UInt32 k = 0; k < morphGroup->presets.count; k++)
  711.             {
  712.                 CharacterCreation::MorphGroup::Preset preset;
  713.                 morphGroup->presets.GetNthItem(k, preset);
  714.  
  715.                 _MESSAGE("Morph Index: %08X, Name: %s, Morph: %s", preset.index, preset.name.data ? preset.name.data->Get<char>() : "", preset.morph.data ? preset.morph.data->Get<char>() : "");
  716.                 gLog.Indent();
  717.                 if(preset.texture)
  718.                 {
  719.                     for(UInt32 n = 0; n < 8; n++)
  720.                     {
  721.                         _MESSAGE("%d - %s", n, preset.texture->texture[n].str.data ? preset.texture->texture[n].str.data->Get<char>() : "");
  722.                     }
  723.                 }
  724.                 gLog.Outdent();
  725.             }
  726.             gLog.Outdent();
  727.         }
  728.  
  729.         _MESSAGE("morphSliders");
  730.         gLog.Indent();
  731.         race->morphSliders.Dump();
  732.         gLog.Outdent();
  733.  
  734.         _MESSAGE("WeightMap 1");
  735.         gLog.Indent();
  736.         boneScaleMap->weightMap1.Dump();
  737.         gLog.Outdent();
  738.         _MESSAGE("WeightMap 2");
  739.         gLog.Indent();
  740.         boneScaleMap->weightMap2.Dump();
  741.         gLog.Outdent();
  742.  
  743.         _MESSAGE("morphSetData");
  744.         gLog.Indent();
  745.         if(npc->morphSetData)
  746.         {
  747.             npc->morphSetData->Dump();
  748.         }
  749.         gLog.Outdent();
  750.  
  751.         _MESSAGE("morphRegionData");
  752.         gLog.Indent();
  753.         if(npc->morphRegionData)
  754.         {
  755.             npc->morphRegionData->Dump();
  756.         }
  757.         gLog.Outdent();
  758.  
  759.         tArray<BGSCharacterTint::Entry*> * tintArray[2];
  760.         tintArray[0] = npc->tints;
  761.         tintArray[1] = pc ? pc->tints : nullptr;
  762.  
  763.         for(UInt32 t = 0; t < 2; t++)
  764.         {
  765.             gLog.Indent();
  766.             if(tintArray[t])
  767.             {
  768.                 if(t == 0)
  769.                     _MESSAGE("NPC Tint Entries: %d", tintArray[t]->count);
  770.                 if(t == 1)
  771.                     _MESSAGE("PC Tint Entries: %d", tintArray[t]->count);
  772.  
  773.                 for(UInt32 i = 0; i < tintArray[t]->count; i++)
  774.                 {
  775.                     BGSCharacterTint::Entry * entry;
  776.                     tintArray[t]->GetNthItem(i, entry);
  777.  
  778.                     _MESSAGE("Entry: Index: %08X, percent: %d", entry->tintIndex, entry->percent);
  779.                     switch(entry->GetType())
  780.                     {
  781.                         case BGSCharacterTint::Entry::kTypeMask:
  782.                             {
  783.                                 gLog.Indent();
  784.                                 BGSCharacterTint::Template::Mask * templateMask = static_cast<BGSCharacterTint::Template::Mask *>(entry->templateEntry);
  785.                                 if(templateMask)
  786.                                 {
  787.                                     _MESSAGE("Mask: Index: %08X, Name: %s, unk18: %d, unk1E: %d, unk1F: %d, unk28: %08X, unk2C: %08X", templateMask->templateIndex, templateMask->name.data ? templateMask->name.data->Get<char>() : "", templateMask->unk18, templateMask->unk1E, templateMask->unk1F, templateMask->unk28, templateMask->unk2C);
  788.                                     Condition * pCondition = templateMask->conditions;
  789.                                     while(pCondition)
  790.                                     {
  791.                                         ObScriptCommand * cmd = GetCommandByOpcode(pCondition->functionId);
  792.                                         _MESSAGE("Condition: Compare: %f, Type: %d Function: %s, ReferenceType: %d, P1: %016I64X, P2: %016I64X", pCondition->compareValue, pCondition->comparisonType, cmd ? cmd->longName : "no name", pCondition->referenceType, pCondition->param1.form, pCondition->param2.form);
  793.                                         pCondition = pCondition->next;
  794.                                     }
  795.                                 }
  796.                                 gLog.Outdent();
  797.                             }
  798.                             break;
  799.                         case BGSCharacterTint::Entry::kTypeTexture:
  800.                             {
  801.                                 gLog.Indent();
  802.                                 BGSCharacterTint::Template::TexureSet * templateTexture = static_cast<BGSCharacterTint::Template::TexureSet *>(entry->templateEntry);
  803.                                 if(templateTexture)
  804.                                 {
  805.                                     _MESSAGE("Texture: Index: %08X, Name: %s, unk18: %d, unk1E: %d, unk1F: %d, unk38: %08X, unk3C: %08X", templateTexture->templateIndex, templateTexture->name.data ? templateTexture->name.data->Get<char>() : "", templateTexture->unk18, templateTexture->unk1E, templateTexture->unk1F, templateTexture->unk38, templateTexture->unk3C);
  806.                                     gLog.Indent();
  807.                                     _MESSAGE("Diffuse: %s", templateTexture->diffuse.data ? templateTexture->diffuse.data->Get<char>() : "Empty");
  808.                                     _MESSAGE("Normal: %s", templateTexture->specular.data ? templateTexture->specular.data->Get<char>() : "Empty");
  809.                                     _MESSAGE("Specular: %s", templateTexture->normal.data ? templateTexture->normal.data->Get<char>() : "Empty");
  810.                                     gLog.Outdent();
  811.                                     Condition * pCondition = templateTexture->conditions;
  812.                                     while(pCondition)
  813.                                     {
  814.                                         ObScriptCommand * cmd = GetCommandByOpcode(pCondition->functionId);
  815.                                         _MESSAGE("Condition: Compare: %f, Type: %d Function: %s, ReferenceType: %d, P1: %016I64X, P2: %016I64X", pCondition->compareValue, pCondition->comparisonType, cmd ? cmd->longName : "no name", pCondition->referenceType, pCondition->param1.form, pCondition->param2.form);
  816.                                         pCondition = pCondition->next;
  817.                                     }
  818.                                 }
  819.                                 gLog.Outdent();
  820.                             }
  821.                             break;
  822.                         case BGSCharacterTint::Entry::kTypePalette:
  823.                             {
  824.                                 gLog.Indent();
  825.                                 BGSCharacterTint::PaletteEntry* paletteEntry = static_cast<BGSCharacterTint::PaletteEntry*>(entry);
  826.                                 _MESSAGE("Palette: color: %08X, colorID: %04X", paletteEntry->color, paletteEntry->colorID);
  827.  
  828.                                 BGSCharacterTint::Template::Palette * templatePalette = static_cast<BGSCharacterTint::Template::Palette *>(entry->templateEntry);
  829.                                 if(templatePalette)
  830.                                 {
  831.                                    
  832.                                     _MESSAGE("Mask: Index: %08X, Name: %s, unk18: %d, unk1E: %d, unk1F: %d, unk28: %08X, unk2C: %08X", templatePalette->templateIndex, templatePalette->name.data ? templatePalette->name.data->Get<char>() : "", templatePalette->unk18, templatePalette->unk1E, templatePalette->unk1F, templatePalette->unk28, templatePalette->unk2C);
  833.                                     gLog.Indent();
  834.                                     for(UInt32 k = 0; k < templatePalette->colors.count; k++)
  835.                                     {
  836.                                         BGSCharacterTint::Template::Palette::ColorData colorData;
  837.                                         templatePalette->colors.GetNthItem(k, colorData);
  838.                                         _MESSAGE("Color: Name: %s FormID: %08X, Color: %08X, alpha: %f, unk0C: %08X, colorID: %04X, unk12: %04X, unk14: %04X", colorData.colorForm->fullName.name.data ? colorData.colorForm->fullName.name.data->Get<char>() : "", colorData.colorForm->formID, colorData.colorForm->color.rgb, colorData.alpha, colorData.unk0C, colorData.colorID, colorData.unk12, colorData.unk14);
  839.                                     }
  840.                                     gLog.Outdent();
  841.                                     Condition * pCondition = templatePalette->conditions;
  842.                                     while(pCondition)
  843.                                     {
  844.                                         ObScriptCommand * cmd = GetCommandByOpcode(pCondition->functionId);
  845.                                         _MESSAGE("Condition: Compare: %f, Type: %d Function: %s, ReferenceType: %d, P1: %016I64X, P2: %016I64X", pCondition->compareValue, pCondition->comparisonType, cmd ? cmd->longName : "no name", pCondition->referenceType, pCondition->param1.form, pCondition->param2.form);
  846.                                         pCondition = pCondition->next;
  847.                                     }
  848.                                    
  849.                                 }
  850.                                 gLog.Outdent();
  851.                             }
  852.                             break;
  853.                    
  854.                     }
  855.  
  856.                 }
  857.             }
  858.             gLog.Outdent();
  859.         }*/
  860.     }
  861.  
  862.     Console_Print("F4SE test func executed");
  863.     return true;
  864. }
  865. #endif
  866.  
  867. void Hooks_ObScript_Commit()
  868. {
  869.     ObScriptCommand cmd = *s_hijackedCommand;
  870.  
  871.     cmd.longName = "GetF4SEVersion";
  872.     cmd.shortName = "";
  873.     cmd.helpText = "";
  874.     cmd.needsParent = 0;
  875.     cmd.numParams = 0;
  876.     cmd.execute = GetF4SEVersion_Execute;
  877.     cmd.flags = 0;
  878.  
  879.     SafeWriteBuf((uintptr_t)s_hijackedCommand, &cmd, sizeof(cmd));
  880.  
  881. #ifdef _DEBUG
  882.     if(s_testCommand)
  883.     {
  884.         ObScriptCommand testcmd = *s_testCommand;
  885.  
  886.         testcmd.longName = "F4SETestCode";
  887.         testcmd.shortName = "";
  888.         testcmd.helpText = "";
  889.         testcmd.needsParent = 0;
  890.         testcmd.numParams = 0;
  891.         testcmd.params = nullptr;
  892.         testcmd.execute = F4SETestCode_Execute;
  893.         testcmd.flags = 0;
  894.  
  895.         SafeWriteBuf((uintptr_t)s_testCommand, &testcmd, sizeof(testcmd));
  896.     }
  897. #endif
  898.  
  899.     {
  900.         struct GetActorBaseHeadData_Code : Xbyak::CodeGenerator {
  901.             GetActorBaseHeadData_Code(void * buf, UInt64 funcAddr) : Xbyak::CodeGenerator(4096, buf)
  902.             {
  903.                 Xbyak::Label funcLabel;
  904.                 Xbyak::Label retnLabel;
  905.  
  906.                 mov(rcx, r15);
  907.                 call(ptr [rip + funcLabel]);
  908.                 mov(rcx, rax);
  909.                 jmp(ptr [rip + retnLabel]);
  910.  
  911.                 L(funcLabel);
  912.                 dq(funcAddr);
  913.  
  914.                 L(retnLabel);
  915.                 dq(GetActorBaseHeadData_Start.GetUIntPtr() + 0x07);
  916.             }
  917.         };
  918.  
  919.         void * codeBuf = g_localTrampoline.StartAlloc();
  920.         GetActorBaseHeadData_Code code(codeBuf, (uintptr_t)GetActorBaseHeadData_Hook);
  921.         g_localTrampoline.EndAlloc(code.getCurr());
  922.  
  923.         g_branchTrampoline.Write6Branch(GetActorBaseHeadData_Start.GetUIntPtr(), uintptr_t(code.getCode()));
  924.     }
  925.  
  926.     {
  927.         struct GetMorphGroups_Code : Xbyak::CodeGenerator {
  928.             GetMorphGroups_Code(void * buf, UInt64 funcAddr) : Xbyak::CodeGenerator(4096, buf)
  929.             {
  930.                 Xbyak::Label funcLabel;
  931.                 Xbyak::Label retnLabel;
  932.  
  933.                 mov(rcx, rax);
  934.                 call(ptr [rip + funcLabel]);
  935.                 test(rax, rax);
  936.                 jmp(ptr [rip + retnLabel]);
  937.  
  938.                 L(funcLabel);
  939.                 dq(funcAddr);
  940.  
  941.                 L(retnLabel);
  942.                 dq(GetMorphGroups_Start.GetUIntPtr() + 0x07);
  943.             }
  944.         };
  945.  
  946.         void * codeBuf = g_localTrampoline.StartAlloc();
  947.         GetMorphGroups_Code code(codeBuf, (uintptr_t)GetMorphGroups_Hook);
  948.         g_localTrampoline.EndAlloc(code.getCurr());
  949.  
  950.         g_branchTrampoline.Write6Branch(GetMorphGroups_Start.GetUIntPtr(), uintptr_t(code.getCode()));
  951.     }
  952.  
  953.     g_branchTrampoline.Write5Call(StaticTextureIndexed_Ctor_Start.GetUIntPtr(), (uintptr_t)StaticTextureIndexed_ctor_Hook);
  954.  
  955.  
  956.  
  957.     // hook creation of BSScaleformManager
  958.     {
  959.         struct InitializeSharedTarget_Code : Xbyak::CodeGenerator {
  960.             InitializeSharedTarget_Code(void * buf) : Xbyak::CodeGenerator(4096, buf)
  961.             {
  962.                 Xbyak::Label retnLabel;
  963.  
  964.                 push(rsi);
  965.                 push(rdi);
  966.                 push(r14);
  967.  
  968.                 jmp(ptr [rip + retnLabel]);
  969.  
  970.                 L(retnLabel);
  971.                 dq(InitializeSharedTarget.GetUIntPtr() + 5);
  972.             }
  973.         };
  974.  
  975.         void * codeBuf = g_localTrampoline.StartAlloc();
  976.         InitializeSharedTarget_Code code(codeBuf);
  977.         g_localTrampoline.EndAlloc(code.getCurr());
  978.  
  979.         InitializeSharedTarget_Original = (_InitializeSharedTarget)codeBuf;
  980.  
  981.         g_branchTrampoline.Write5Branch(InitializeSharedTarget.GetUIntPtr(), (uintptr_t)InitializeSharedTarget_Hook);
  982.     }
  983. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement