Advertisement
momo5502

PatchMW2Experimtents.cpp

Mar 30th, 2013
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 33.93 KB | None | 0 0
  1. // ==========================================================
  2. // IW4M project
  3. //
  4. // Component: clientdll
  5. // Sub-component: steam_api
  6. // Purpose: Modern Warfare 2 patches: experimental dev code
  7. //
  8. // Initial author: NTAuthority
  9. // Started: 2011-05-09
  10. // ==========================================================
  11.  
  12. #include "StdInc.h"
  13. #include <shlobj.h>
  14. #include <direct.h>
  15. #include <unordered_map>
  16.  
  17. typedef void* (__cdecl * LoadRawFile_t)(const char* filename, void* buffer, size_t buflen);
  18. LoadRawFile_t LoadRawFile = (LoadRawFile_t)0x4DA0D0;
  19.  
  20. CallHook addEntryNameHook;
  21. DWORD addEntryNameHookLoc = 0x5BB697;
  22.  
  23. StompHook endLoadingHook;
  24. DWORD endLoadingHookLoc = 0x4E5E5C;
  25.  
  26. #define MAX_RAWFILE_NAMES 32768
  27. static const char* rawFileNames[MAX_RAWFILE_NAMES];
  28. static int currentRawFile = 0;
  29.  
  30. #define MAX_STABLE_NAMES 32768
  31. static const char* sTableNames[MAX_STABLE_NAMES];
  32. static int currentSTable = 0;
  33.  
  34. #define RAWFILE_BUFSIZE 2097152
  35. static char rawFileBuffer[RAWFILE_BUFSIZE];
  36.  
  37. typedef struct stringTable_s {
  38.     char* fileName;
  39.     int columns;
  40.     int rows;
  41.     char** data;
  42. } stringTable_t;
  43.  
  44. stringTable_t* stringTable;
  45.  
  46. bool useEntryNames = false;
  47.  
  48. void AddEntryNameHookFunc(int type, const char* name)
  49. {
  50.     if (GAME_FLAG(GAME_FLAG_ENTRIES) || useEntryNames)
  51.     {
  52.         OutputDebugString(va("%d: %s\n", type, name));
  53.     }
  54.  
  55.     /*if (type == ASSET_TYPE_STRINGTABLE)
  56.     {
  57.         if (currentSTable < MAX_STABLE_NAMES)
  58.         {
  59.             sTableNames[currentSTable] = name;
  60.             currentSTable++;
  61.         }
  62.     }
  63.     return;
  64.  
  65.     if (type == ASSET_TYPE_RAWFILE)
  66.     {
  67.         if (currentRawFile < MAX_RAWFILE_NAMES)
  68.         {
  69.             rawFileNames[currentRawFile] = name;
  70.             currentRawFile++;
  71.         }
  72.     }*/
  73. }
  74.  
  75. void DumpRawFiles()
  76. {
  77.     if (Cmd_Argc() != 2)
  78.     {
  79.         return;
  80.     }
  81.  
  82.     rawFileNames[0] = Cmd_Argv(1);
  83.     currentRawFile = 1;
  84.  
  85.     for (int i = 0; i < currentRawFile; i++)
  86.     {
  87.         const char* name = rawFileNames[i];
  88.         memset(rawFileBuffer, 0, RAWFILE_BUFSIZE);
  89.  
  90.         if (LoadRawFile(name, rawFileBuffer, RAWFILE_BUFSIZE))
  91.         {
  92.             char filename[512];
  93.             char dir[512];
  94.             size_t length = strlen(rawFileBuffer);
  95.             sprintf(filename, "%s/%s", "maw", name);
  96.  
  97.             GetCurrentDirectoryA(sizeof(dir), dir);
  98.             strcat(dir, "/");
  99.             strcat(dir, filename);
  100.             *(strrchr(dir, '/')) = '\0';
  101.  
  102.             size_t strl = strlen(dir);
  103.  
  104.             for (size_t i = 0; i < strl; i++)
  105.             {
  106.                 if (dir[i] == '/') dir[i] = '\\';
  107.             }
  108.  
  109.             SHCreateDirectoryExA(NULL, dir, NULL);
  110.  
  111.             FILE* file = fopen(filename, "wb");
  112.  
  113.             if (file)
  114.             {
  115.                 fwrite(rawFileBuffer, 1, length, file);
  116.                 fclose(file);
  117.             }
  118.         }
  119.     }
  120.  
  121.     currentRawFile = 0;
  122.  
  123.     /*for (int i = 0; i < currentSTable; i++)
  124.     {
  125.         const char* name = sTableNames[i];
  126.         stringTable_t* stringTable;
  127.  
  128.         if (stringTable = (stringTable_t*)DB_FindXAssetHeader(37, name))
  129.         {
  130.             char filename[512];
  131.             char dir[512];
  132.             sprintf(filename, "%s/%s", "raw", name);
  133.  
  134.             GetCurrentDirectoryA(sizeof(dir), dir);
  135.             strcat(dir, "/");
  136.             strcat(dir, filename);
  137.             *(strrchr(dir, '/')) = '\0';
  138.  
  139.             size_t strl = strlen(dir);
  140.  
  141.             for (size_t i = 0; i < strl; i++)
  142.             {
  143.                 if (dir[i] == '/') dir[i] = '\\';
  144.             }
  145.  
  146.             SHCreateDirectoryExA(NULL, dir, NULL);
  147.  
  148.             FILE* file = fopen(filename, "w");
  149.  
  150.             if (file)
  151.             {
  152.                 int currentColumn = 0;
  153.                 int currentRow = 0;
  154.                 int total = stringTable->columns * stringTable->rows;
  155.  
  156.                 for (int i = 0; i < total; i++) {
  157.                     char* current = stringTable->data[i * 2];
  158.  
  159.                     fprintf(file, "%s", current);
  160.  
  161.                     bool isNext = ((i + 1) % stringTable->columns) == 0;
  162.  
  163.                     if (isNext) {
  164.                         fprintf(file, "\n");
  165.                     } else {
  166.                         fprintf(file, ",");
  167.                     }
  168.  
  169.                     fflush(file);
  170.                 }
  171.  
  172.                 fclose(file);
  173.             }
  174.         }
  175.     }
  176.  
  177.     currentSTable = 0;*/
  178. }
  179.  
  180. void __declspec(naked) EndLoadingHookStub()
  181. {
  182.     __asm
  183.     {
  184.         mov eax, 05091E0h
  185.         call eax
  186.         call DumpRawFiles
  187.         retn
  188.     }
  189. }
  190.  
  191. void __declspec(naked) AddEntryNameHookStub()
  192. {
  193.     __asm
  194.     {
  195.         push ecx
  196.         push eax
  197.         call AddEntryNameHookFunc
  198.         pop eax
  199.         pop ecx
  200.         jmp addEntryNameHook.pOriginal
  201.     }
  202. }
  203.  
  204. typedef struct weaponEntry_s
  205. {
  206.     const char* name;
  207.     int offset;
  208.     int type;
  209. } weaponEntry_t;
  210.  
  211. #define NUM_ENTRIES 672
  212. #define NUM_VEHICLE_ENTRIES 143
  213.  
  214. #define WEAPON_DO_ARRAY(ar, c) \
  215. { \
  216.     for (int _l_1 = 0; _l_1 < c; _l_1++) \
  217.     { \
  218.         if (*(int*)data == _l_1) \
  219.         { \
  220.             fprintf(file, "%s", ((char**)ar)[_l_1]); /* why do I have to explicitly define ar as being a char**? */ \
  221.         } \
  222.     } \
  223. }
  224.  
  225. weaponEntry_t* weaponEntries = (weaponEntry_t*)0x795F00;
  226. weaponEntry_t* vehicleEntries = (weaponEntry_t*)0x79F2E8;
  227.  
  228. const char* SL_ConvertToString(unsigned int sl)
  229. {
  230.     __asm
  231.     {
  232.         push sl
  233.         mov eax, 4EC1D0h
  234.         call eax
  235.         add esp, 4h
  236.         mov sl, eax
  237.     }
  238.  
  239.     return (const char*)sl;
  240. }
  241.  
  242. void DumpNoteTrackEntry(FILE* file, int type, char* data, char* data2)
  243. {
  244.     switch (type)
  245.     {
  246.         case 39: // notetrack-to-sound
  247.         case 40: // notetrack-to-rumble
  248.             {
  249.                 // as seen last time, SL is usable now.
  250.                 short* keys = *(short**)data;
  251.                 short* values = *(short**)data2;
  252.  
  253.                 for (int i = 0; i < 16; i++)
  254.                 {
  255.                     short key = keys[i];
  256.                     short value = values[i];
  257.  
  258.                     if (key)
  259.                     {
  260.                         fprintf(file, "%s %s%s", SL_ConvertToString(key), SL_ConvertToString(value), (i == 15 || keys[i + 1] == 0) ? "" : "\n"); // it seems like a newline is needed for all but the last tag
  261.                     }
  262.                 }
  263.             }
  264.             break;
  265.     }
  266. }
  267.  
  268. bool thisIsWeaponfile = true;
  269.  
  270. void DumpEntry(FILE* file, int type, char* data)
  271. {
  272.     switch (type)
  273.     {
  274.     case 0: // string
  275.         {
  276.             char* str = (char*)(*(DWORD_PTR*)data);
  277.  
  278.             if (str && (int)str != 0xFFFFFFFF && (int)str > 16)
  279.             {
  280.                 fprintf(file, "%s", str);
  281.             }
  282.             break;
  283.         }
  284.     case 1: // char[1024]
  285.     case 2: // char[64]
  286.     case 3: // char[256]
  287.         {
  288.             fprintf(file, "%s", *(char**)data);
  289.             break;
  290.         }
  291.     case 4:
  292.     case 5: // bool-as-int
  293.         {
  294.             int number = *(int*)data;
  295.  
  296.             fprintf(file, "%d", number);
  297.             break;
  298.         }
  299.     case 6:
  300.         {
  301.             bool boolean = *(bool*)data;
  302.  
  303.             fprintf(file, "%d", (boolean) ? 1 : 0);
  304.             break;
  305.         }
  306.     case 7:
  307.         {
  308.             float number = *(float*)data;
  309.  
  310.             fprintf(file, "%g", number);
  311.             break;
  312.         }
  313.     case 8:
  314.         {
  315.             float number = *(float*)data;
  316.  
  317.             fprintf(file, "%g", (number / 17.6f)); // miles/hour - inch/sec
  318.             break;
  319.         }
  320.     case 9:
  321.         {
  322.             int number = *(int*)data;
  323.  
  324.             fprintf(file, "%g", (number / 1000.0f));
  325.             break;
  326.         }
  327.     case 16:
  328.         if (thisIsWeaponfile)
  329.         {
  330.             WEAPON_DO_ARRAY(0x795DA0, 4)
  331.         }
  332.         else
  333.         {
  334.             WEAPON_DO_ARRAY(0x79F2C0, 7)
  335.         }
  336.         break;
  337.     case 17:
  338.         if (thisIsWeaponfile)
  339.         {
  340.             WEAPON_DO_ARRAY(0x795DB0, 12)
  341.         }
  342.         else
  343.         {
  344.             WEAPON_DO_ARRAY(0x79F2DC, 3)
  345.         }
  346.         break;
  347.     case 18:
  348.         if (thisIsWeaponfile)
  349.         {
  350.             WEAPON_DO_ARRAY(0x795E68, 2)
  351.         }
  352.         else
  353.         {
  354.             WEAPON_DO_ARRAY(0x79F2DC, 3)
  355.         }
  356.         break;
  357.     case 19:
  358.         if (thisIsWeaponfile)
  359.         {
  360.             WEAPON_DO_ARRAY(0x795E10, 4)
  361.         }
  362.         else
  363.         {
  364.             WEAPON_DO_ARRAY(0x79F2DC, 3)
  365.         }
  366.         break;
  367.     case 20:
  368.         WEAPON_DO_ARRAY(0x795E20, 11)
  369.         break;
  370.     case 21:
  371.         WEAPON_DO_ARRAY(0x795E70, 3)
  372.         break;
  373.     case 22:
  374.         WEAPON_DO_ARRAY(0x795E4C, 7)
  375.         break;
  376.     case 23:
  377.         WEAPON_DO_ARRAY(0x795E7C, 6)
  378.         break;
  379.     case 24:
  380.         WEAPON_DO_ARRAY(0x7BE928, *(int*)0x7BDDDC)
  381.         break;
  382.     case 25:
  383.         WEAPON_DO_ARRAY(0x795E94, 3)
  384.         break;
  385.     case 26:
  386.         WEAPON_DO_ARRAY(0x795EA0, 4)
  387.         break;
  388.     case 28:
  389.         WEAPON_DO_ARRAY(0x795EB0, 6)
  390.         break;
  391.     case 29:
  392.         WEAPON_DO_ARRAY(0x795EC8, 3)
  393.         break;
  394.     case 30:
  395.         WEAPON_DO_ARRAY(0x795DE0, 6)
  396.         break;
  397.     case 31:
  398.         WEAPON_DO_ARRAY(0x795DF8, 6)
  399.         break;
  400.     case 32:
  401.         WEAPON_DO_ARRAY(0x795ED4, 7)
  402.         break;
  403.     case 33:
  404.         WEAPON_DO_ARRAY(0x795EF0, 3)
  405.         break;
  406.     case 34:
  407.         WEAPON_DO_ARRAY(0x795EF0, 3) // same as 33
  408.         break;
  409.     case 35:
  410.         WEAPON_DO_ARRAY(0x795EF0, 3) // same as 33
  411.         break;
  412.     case 36:
  413.         WEAPON_DO_ARRAY(0x795EF0, 3) // same as 33
  414.         break;
  415.     case 37:
  416.         WEAPON_DO_ARRAY(0x795EF0, 3) // same as 33
  417.         break;
  418.     case 13: // phys collmap
  419.         break;
  420.     case 10: // fx
  421.     case 11: // xmodel
  422.     case 12: // material
  423.     case 14: // soundalias
  424.     case 15: // tracer
  425.         {
  426.             BYTE* model = (BYTE*)(*(DWORD_PTR*)data);
  427.  
  428.             if (model)
  429.             {
  430.                 char* str = (char*)(*(DWORD_PTR*)model);
  431.  
  432.                 if (str)
  433.                 {
  434.                     fprintf(file, "%s", str);
  435.                 }
  436.             }
  437.             break;
  438.         }
  439.     case 38: // hideTags
  440.         {
  441.             // hopefully we'll have useful shit here, as if we don't, we're screwed
  442.             // for some reason this code made me go deja vu - seems like I've done SL_ConvertToString before.
  443.             short* tags = (short*)data;
  444.             for (int i = 0; i < 32; i++)
  445.             {
  446.                 short tag = tags[i];
  447.  
  448.                 if (tag)
  449.                 {
  450.                     fprintf(file, "%s%s", SL_ConvertToString(tag), (i == 31 || tags[i + 1] == 0) ? "" : "\n"); // it seems like a newline is needed for all but the last tag
  451.                 }
  452.             }
  453.             break;
  454.         }
  455.     case 27: // bounceSound; surface sound
  456.         {
  457.             char*** dat = *(char****)data;
  458.             if (dat != 0)
  459.             {
  460.                 char bounceName[128];
  461.                 strcpy(bounceName, **dat);
  462.                 strrchr(bounceName, '_')[0] = '\0';
  463.  
  464.                 fprintf(file, "%s", bounceName);
  465.             }
  466.             break;
  467.         }
  468.     default:
  469.         fprintf(file, "lol no type %d", type);
  470.         break;
  471.     }
  472. }
  473.  
  474. typedef struct
  475. {
  476.     int offsetStart;
  477.     int pointerOrigin;
  478. } rtOffsetMap_t;
  479.  
  480. // nvm this is just impossible
  481. /*
  482. static rtOffsetMap_t offsetMap[] =
  483. {
  484.     { 116, 4 },
  485.     { 1784, 12 },
  486.     { 1848, 16 },
  487.     { 1996, 120 },
  488.     { 2060, 128 },
  489.     { 2208, 132 },
  490.     { 2356, 140 },
  491.     { 2388, 144 },
  492.     { 2420, 148 },
  493.     { 2452, 152 },
  494.     { 2484, 588 },
  495.     { 2548, 1208 },
  496.     { 2672, 1212 },
  497.     { 2796, 1576 },
  498.     { 0, 0, 0 }
  499. };
  500.  
  501. char* MapOffsetToPointer(char* origin, int offset)
  502. {
  503.     // let's say offset is 120, and origin is 0 (just to be funs)
  504.     // pointer +4 redirects to 1000
  505.     // we want to end up with 1004
  506.  
  507.     int i = 0;
  508.     while (offsetMap[i].offsetStart != 0)
  509.     {
  510.         int max = (offsetMap[i + 1].offsetStart == 0) ? 0x7FFFFF : offsetMap[i + 1].offsetStart;
  511.  
  512.         // as 120 means it should go pointer 4, we should do so here.
  513.         // after that we need to return a resolved pointer (wtf?) from whatever offset we came from
  514.         if (offset >= offsetMap[i].offsetStart && offset < max)
  515.         {
  516.             return MapOffsetToPointer(origin, offset);
  517.         }
  518.     }
  519.  
  520.     return (origin + offset);
  521. }
  522. */
  523.  
  524. /*
  525. *(_DWORD *)(result + 16) = result + 1848;
  526. *(_DWORD *)(result + 120) = result + 1996;
  527. *(_DWORD *)(result + 128) = result + 2060;
  528. *(_DWORD *)(result + 132) = result + 2208;
  529. *(_DWORD *)(result + 140) = result + 2356;
  530. *(_DWORD *)(result + 144) = result + 2388;
  531. *(_DWORD *)(result + 148) = result + 2420;
  532. *(_DWORD *)(result + 152) = result + 2452;
  533. *(_DWORD *)(result + 588) = result + 2484;
  534. *(_DWORD *)(result + 1208) = result + 2548;
  535. *(_DWORD *)(result + 1212) = result + 2672;
  536. *(_DWORD *)(result + 1576) = result + 2796;
  537. */
  538.  
  539. // lolnope again
  540. /*
  541. char* GetPointerForOffset(char* origin, int offset)
  542. {
  543.     char* retptr = origin;
  544.  
  545.     if (offset >= 1784 && offset < 1848)
  546.     {
  547.         retptr = *(BYTE**)(retptr + 12);
  548.         retptr += (offset - 1784);
  549.     }
  550.  
  551.     if (offset >= 1848 && offset < 1996)
  552.     {
  553.         retptr = *(BYTE**)(retptr + 16);
  554.         retptr += (offset - 1848);
  555.     }
  556.  
  557.     if (offset >= 116)
  558.     {
  559.         retptr = *(BYTE**)(retptr + 4);
  560.         retptr += (offset - 116);
  561.     }
  562.  
  563.     if (offset >= 1996 && offset < 2060)
  564.     {
  565.         retptr = *(BYTE**)(retptr + 4);
  566.         retptr += (offset - 1996);
  567.     }
  568. }
  569. */
  570.  
  571. #define NUM_OFFSET_MAPS 14
  572.  
  573. static rtOffsetMap_t offsetMap[] =
  574. {
  575.     { 116, 4 },
  576.     { 1784, 12 },
  577.     { 1848, 16 },
  578.     { 1996, 120 },
  579.     { 2060, 128 },
  580.     { 2208, 132 },
  581.     { 2356, 140 },
  582.     { 2388, 144 },
  583.     { 2420, 148 },
  584.     { 2452, 152 },
  585.     { 2484, 588 },
  586.     { 2548, 1208 },
  587.     { 2672, 1212 },
  588.     { 2796, 1576 },
  589.     { 0, 0 }
  590. };
  591.  
  592. char* MapOffsetToPointer(char* origin, int offset)
  593. {
  594.     if (!thisIsWeaponfile)
  595.     {
  596.         return (origin + offset);
  597.     }
  598.  
  599.     for (int i = (NUM_OFFSET_MAPS - 1); i >= 0; i--)
  600.     {
  601.         rtOffsetMap_t* current = &offsetMap[i];
  602.         rtOffsetMap_t* next = &offsetMap[i + 1];
  603.  
  604.         int max = next->offsetStart;
  605.         if (max == 0) max = 0xFFFFFF;
  606.  
  607.         if (offset >= current->offsetStart && offset < max)
  608.         {
  609.             char* pointer = *(char**)MapOffsetToPointer(origin, current->pointerOrigin);
  610.             return (pointer + (offset - current->offsetStart));
  611.         }
  612.     }
  613.  
  614.     return (origin + offset);
  615. }
  616.  
  617. void DumpWeaponFile(FILE* file, char* data)
  618. {
  619.     for (int i = 0; i < ((thisIsWeaponfile) ? NUM_ENTRIES : NUM_VEHICLE_ENTRIES); i++)
  620.     {
  621.         weaponEntry_t* entry = (thisIsWeaponfile) ? &weaponEntries[i] : &vehicleEntries[i];
  622.  
  623.         char* ptr = MapOffsetToPointer(data, entry->offset);//(data + entry->offset);
  624.  
  625.         // quick patch to not export empty models (causes too large weaponfiles)
  626.         if (entry->type == 11 && *(int*)ptr == 0)
  627.         {
  628.             continue;
  629.         }
  630.  
  631.         // same for empty strings
  632.         if (entry->type == 0)
  633.         {
  634.             char* str = (char*)(*(DWORD_PTR*)ptr);
  635.  
  636.             if (str && (int)str != 0xFFFFFFFF && (int)str > 16 && *str != 0)
  637.             {
  638.                 // yeah I know, but it's 3:45 AM and I'm too lazy to invert this
  639.             }
  640.             else
  641.             {
  642.                 continue;
  643.             }
  644.         }
  645.  
  646.         fprintf(file, "%s\\", entry->name);
  647.  
  648.         /*if (entry->offset > 116)
  649.         {
  650.             ptr = *(BYTE**)(data + 4);
  651.             ptr += (entry->offset - 116);
  652.         }*/
  653.  
  654.         if (entry->type == 39 || entry->type == 40)
  655.         {
  656.             DumpNoteTrackEntry(file, entry->type, MapOffsetToPointer(data, 140), MapOffsetToPointer(data, 144));
  657.         }
  658.         else
  659.         {
  660.             DumpEntry(file, entry->type, ptr);
  661.         }
  662.  
  663.         if (i < (((thisIsWeaponfile) ? NUM_ENTRIES : NUM_VEHICLE_ENTRIES) - 1))
  664.         {
  665.             fprintf(file, "\\");
  666.         }
  667.     }
  668. }
  669.  
  670. void DumpWeaponTypes(FILE* file)
  671. {
  672.     for (int i = 0; i < NUM_ENTRIES; i++)
  673.     {
  674.         weaponEntry_t* entry = &weaponEntries[i];
  675.  
  676.         //fprintf(file, "%s\\", entry->name);
  677.  
  678.         //DumpEntry(file, entry->type, (data + entry->offset));
  679.  
  680.         fprintf(file, "+0x%x:\t%s", entry->offset, entry->name);
  681.  
  682.         switch (entry->type)
  683.         {
  684.         case 0:
  685.             fprintf(file, " (string)");
  686.             break;
  687.         case 7:
  688.             fprintf(file, " (float)");
  689.             break;
  690.         case 8:
  691.             fprintf(file, " (float / 17.6)");
  692.             break;
  693.         case 9:
  694.             fprintf(file, " (float / 1000.0)");
  695.             break;
  696.         case 11:
  697.             fprintf(file, " (xmodel)");
  698.             break;
  699.         case 0xD:
  700.             fprintf(file, " (phys collmap)");
  701.             break;
  702.         default:
  703.             fprintf(file, " (type %d)", entry->type);
  704.             break;
  705.         }
  706.  
  707.         fprintf(file, "\n");
  708.     }
  709. }
  710.  
  711. StompHook weaponFileHook;
  712. DWORD weaponFileHookLoc = 0x57B650;
  713.  
  714. void* WeaponFileHookFunc(const char* filename)
  715. {
  716.     //if (!_stricmp(filename, "m40a3") || !_stricmp(filename, "winchester1200") || !_stricmp(filename, "mg4_heartbeat_mp") || !_stricmp(filename, "famas_mp") || !_stricmp(filename, "ak47_mp") || !_stricmp(filename, "cheytac_mp"))
  717.     /*if (!Legacy_IsLegacyMode())
  718.     {
  719.         if (!_stricmp(filename, "destructible_car") || !_stricmp(filename, "none"))
  720.         {
  721.             return DB_FindXAssetHeader(ASSET_TYPE_WEAPON, "defaultweapon_mp");
  722.         }
  723.     }*/
  724.  
  725.     if (FS_ReadFile(va("weapons/mp/%s", filename), NULL) > 0)
  726.     {
  727.         return ((void* (*)(const char*))0x57B5F0)(filename); // BG_LoadWeaponDef_LoadObj
  728.     }
  729.  
  730.     char* file = (char*)DB_FindXAssetHeader(0x1C, filename);
  731.  
  732.     if (GAME_FLAG(GAME_FLAG_DUMPDATA))
  733.     {
  734.         _mkdir("raw\\weapons");
  735.         _mkdir("raw\\weapons\\mp");
  736.  
  737.         char dumpfile[512];
  738.         strcpy(dumpfile, "raw\\weapons\\mp\\");
  739.         strcat(dumpfile, filename);
  740.  
  741.         FILE* dump = fopen(dumpfile, "w");
  742.         fprintf(dump, "WEAPONFILE\\");
  743.  
  744.         thisIsWeaponfile = true;
  745.         DumpWeaponFile(dump, file);
  746.  
  747.         fclose(dump);
  748.  
  749.         //dump = fopen("raw\\weaponFields.txt", "w");
  750.         //DumpWeaponTypes(dump);
  751.         //fclose(dump);
  752.     }
  753.  
  754.     //TerminateProcess(GetCurrentProcess(), 0);
  755.  
  756.     return file;
  757. }
  758.  
  759. void __declspec(naked) WeaponFileHookStub()
  760. {
  761.     __asm jmp WeaponFileHookFunc
  762. }
  763.  
  764. StompHook vehicleFileHook;
  765. DWORD vehicleFileHookLoc = 0x67CD40;
  766.  
  767. void* G_LoadVehicleDef(const char* filename);
  768.  
  769. void* VehicleFileHookFunc(const char* filename)
  770. {
  771.     if (FS_ReadFile(va("vehicles/%s", filename), NULL) > 0)
  772.     {
  773.         //return G_LoadVehicleDef(filename);
  774.     }
  775.  
  776.     char* file = (char*)DB_FindXAssetHeader(ASSET_TYPE_VEHICLE, filename);
  777.  
  778.     if (GAME_FLAG(GAME_FLAG_DUMPDATA))
  779.     {
  780.         _mkdir("raw\\vehicles");
  781.         _mkdir("raw\\vehicles\\mp");
  782.  
  783.         char dumpfile[512];
  784.         strcpy(dumpfile, "raw\\vehicles\\mp\\");
  785.         strcat(dumpfile, filename);
  786.  
  787.         FILE* dump = fopen(dumpfile, "w");
  788.         fprintf(dump, "VEHICLEFILE\\");
  789.  
  790.         thisIsWeaponfile = false;
  791.         DumpWeaponFile(dump, file);
  792.  
  793.         fclose(dump);
  794.     }
  795.  
  796.     return file;
  797. }
  798.  
  799. StompHook scriptOddLogHook;
  800. DWORD scriptOddLogHookLoc = 0x4938D0;
  801.  
  802. StompHook scriptOddLogHook2;
  803. DWORD scriptOddLogHook2Loc = 0x49D3F0;
  804.  
  805. void ScriptOddLogHookFunc(int meh, char* mehh)
  806. {
  807.     Com_Printf(0, "sd: %s\n", mehh);
  808. }
  809.  
  810. void __declspec(naked) ScriptOddLogHookStub()
  811. {
  812.     __asm jmp ScriptOddLogHookFunc
  813. }
  814.  
  815. // HELL YEAH PART 2 OF ODD LOG HOOK
  816. void ScriptOddLogHook2Func(char* mehh)
  817. {
  818.     Com_Printf(0, "sd: %s\n", mehh);
  819. }
  820.  
  821. void __declspec(naked) ScriptOddLogHook2Stub()
  822. {
  823.     __asm jmp ScriptOddLogHook2Func // if it breaks spawning, firstly go 'wtf'.
  824. }
  825.  
  826. // debug hook to find whoever fucked with my party state
  827. CallHook psClearHook;
  828. DWORD psClearHookLoc = 0x48569C;
  829.  
  830. int curret;
  831.  
  832. void __declspec(naked) PsClearHookStub()
  833. {
  834.     __asm
  835.     {
  836.         mov eax, [esp + 14h]
  837.         mov curret, eax
  838.     }
  839.  
  840.     Com_Printf(0, "GUILTY AS CHARGED AT 0x%x\n", curret);
  841.  
  842.     __asm retn
  843. }
  844.  
  845. CallHook modelOverflowHook;
  846. DWORD modelOverflowHookLoc = 0x44F265;
  847.  
  848. void ModelOverflowHookFunc()
  849. {
  850.     for (int i = 1125; i < (1125 + 512); i++)
  851.     {
  852.         unsigned int string;
  853.         __asm
  854.         {
  855.             push i
  856.             mov eax, 468500h
  857.             call eax
  858.             add esp, 4h
  859.             mov string, eax
  860.         }
  861.  
  862.         if (string)
  863.         {
  864.             Com_Printf(0, "\t%i: %s\n", i, SL_ConvertToString(string));
  865.         }
  866.     }
  867. }
  868.  
  869. void __declspec(naked) ModelOverflowHookStub()
  870. {
  871.     __asm
  872.     {
  873.         pushad
  874.         call ModelOverflowHookFunc
  875.         popad
  876.         jmp modelOverflowHook.pOriginal
  877.     }
  878. }
  879.  
  880. void* MaterialLoadHookFunc(assetType_t type, const char* filename);
  881.  
  882. cmd_function_t mehCmd;
  883. XModel* WeaponCamos_Init();
  884. void MehFunc()
  885. {
  886.     /*Material* material = (Material*)DB_FindXAssetHeader(ASSET_TYPE_MATERIAL, "preview_mp_boneyard");
  887.     Material* material2 = (Material*)MaterialLoadHookFunc(ASSET_TYPE_MATERIAL, "preview_oilrig");
  888.     void* image = DB_FindXAssetHeader(ASSET_TYPE_IMAGE, "3_cursor3");*/
  889.  
  890.     //Material* material = (Material*)MaterialLoadHookFunc(ASSET_TYPE_MATERIAL, "$floatz");
  891.     XModel* xmodel = (XModel*)DB_FindXAssetHeader(ASSET_TYPE_XMODEL, "weapon_usp");
  892.  
  893.     //Com_Printf(0, "HASH: 0x%x\n", R_HashString("colorMap"));
  894.  
  895.     for (int i = 0; i < xmodel->numMaterials; i++)
  896.     {
  897.         Com_Printf(0, "MAT NAME: %s\n", xmodel->materials[i]->name);
  898.  
  899.         for (int j = 0; j < xmodel->materials[i]->numMaps; j++)
  900.         {
  901.             Com_Printf(0, "IMAGE NAME #%d: %s\n", j, xmodel->materials[i]->maps[j].image->name);
  902.         }
  903.     }
  904.  
  905.     printf("Yep.");
  906. }
  907.  
  908. void SndAliasListFunc()
  909. {
  910.     if (Cmd_Argc() < 2)
  911.     {
  912.         return;
  913.     }
  914.  
  915.     const char* name = Cmd_Argv(1);
  916.     snd_alias_list_t* list = (snd_alias_list_t*)DB_FindXAssetHeader(ASSET_TYPE_SOUND, name);
  917.  
  918.     Com_Printf(0, "%s\n", list->aliases[0].stream->file);
  919. }
  920.  
  921. struct localizedEntry_s
  922. {
  923.     const char* value;
  924.     const char* name;
  925. };
  926.  
  927. //#include <d3dx9.h>
  928.  
  929. void AssetRestrict_PreLoadFromExperimental(assetType_t type, void* entry, const char* zone)
  930. {
  931.     /*if (type == ASSET_TYPE_VERTEXSHADER)
  932.     {
  933.         VertexShader* shader = (VertexShader*)entry;
  934.  
  935.         if (shader->bytecode)
  936.         {
  937.             ID3DXBuffer* buffer;
  938.             D3DXDisassembleShader(shader->bytecode, TRUE, NULL, &buffer);
  939.  
  940.             FILE* shaderDisassembly = fopen(va("raw/%s.html", shader->name), "w");
  941.             fwrite(buffer->GetBufferPointer(), 1, buffer->GetBufferSize(), shaderDisassembly);
  942.             fclose(shaderDisassembly);
  943.  
  944.             buffer->Release();
  945.         }
  946.     }*/
  947.  
  948.     // fix for sort keys
  949.     /*if (type == ASSET_TYPE_MATERIAL)
  950.     {
  951.         const char* name = *(char**)entry;
  952.  
  953.         if (strstr(name, "distortion"))
  954.         {
  955.             Material* mat = (Material*)entry;
  956.  
  957.             if ((mat->flags >> 8) == 44)
  958.             {
  959.                 mat->flags = (mat->flags & 0xFF) | (43 << 8);
  960.             }
  961.         }
  962.     }*/
  963. /*
  964.     return;
  965.  
  966.     if (type == ASSET_TYPE_MATERIAL)
  967.     {
  968.         const char* name = *(char**)entry;
  969.  
  970.         if (strstr(name, "distortion") && name[0] != ',')
  971.         {
  972.             Material* mat = (Material*)entry;
  973.  
  974.             OutputDebugString(va("distortion %s: firstChar %d, secLast %d, unk1 %d, unk2 %d\n", name, mat->maps[0].firstCharacter, mat->maps[0].secondLastCharacter, mat->maps[0].unknown, mat->maps[0].unknown2));
  975.         }
  976.     }
  977.  
  978.     if (type == ASSET_TYPE_XANIM)
  979.     {
  980.         const char* name = *(char**)entry;
  981.  
  982.         if (strstr(name, "lobby"))
  983.         {
  984.             char* anim = (char*)entry;
  985.  
  986.             OutputDebugString(va("anim %s: %g rate, %g freq, %i frame\n", name, *(float*)(anim + 40), *(float*)(anim + 44), *(short*)(anim + 14)));
  987.         }
  988.     }
  989.     return;
  990.  
  991.     if (type == ASSET_TYPE_MATERIAL)
  992.     {
  993.         Material* material = (Material*)entry;
  994.  
  995.         if (material->maps)
  996.         {
  997.             if (material->maps[0].image)
  998.             {
  999.                 if (material->maps[0].image->name)
  1000.                 {
  1001.                     //OutputDebugStringA(va("'%s' => '%s',\n", material->name, material->maps[0].image->name));
  1002.                 }
  1003.             }
  1004.         }
  1005.  
  1006.         if (material->animationX > 1 || material->animationY > 1)
  1007.         {
  1008.             OutputDebugStringA(va("'%s' => array(%d, %d),", material->name, material->animationX, material->animationY));
  1009.         }
  1010.     }
  1011.     */
  1012.     if (type == ASSET_TYPE_LOCALIZE)
  1013.     {
  1014.         _mkdir("raw/english/");
  1015.         _mkdir("raw/english/localizedstrings/");
  1016.  
  1017.         char nameStuff[512];
  1018.         char valueStuff[1024];
  1019.         localizedEntry_s* ent = (localizedEntry_s*)entry;
  1020.         const char* module = "unknown";
  1021.  
  1022.         strcpy_s(nameStuff, sizeof(nameStuff), ent->name);
  1023.  
  1024.         char* entryName = strchr(nameStuff, '_');
  1025.         entryName[0] = '\0';
  1026.         entryName++;
  1027.  
  1028.         for (char* pt = nameStuff; *pt; pt++)
  1029.         {
  1030.             *pt = tolower(*pt);
  1031.         }
  1032.  
  1033.         char* p2 = &valueStuff[0];
  1034.         for (const char* pt = ent->value; *pt; pt++)
  1035.         {
  1036.             char c = *pt;
  1037.             if (c == '\n')
  1038.             {
  1039.                 *p2 = '\\';
  1040.                 p2++;
  1041.                 *p2 = 'n';
  1042.             }
  1043.             else if (c == '"')
  1044.             {
  1045.                 *p2 = '\\';
  1046.                 p2++;
  1047.                 *p2 = '"';
  1048.             }
  1049.             else
  1050.             {
  1051.                 *p2 = c;
  1052.             }
  1053.  
  1054.             p2++;
  1055.         }
  1056.  
  1057.         *p2 = '\0';
  1058.  
  1059.         FILE* file = fopen(va("raw/english/localizedstrings/%s.str", nameStuff), "a");
  1060.  
  1061.         if (file)
  1062.         {
  1063.             fprintf(file, "REFERENCE           %s\n", entryName);
  1064.             fprintf(file, "LANG_ENGLISH        \"%s\"\n\n", valueStuff);
  1065.             fclose(file);
  1066.         }
  1067.     }
  1068. }
  1069.  
  1070. extern const char* allowedImagery[];
  1071. std::unordered_map<std::string, bool> _allowedAssetMap;
  1072.  
  1073. void InitializeImageLoad()
  1074. {
  1075.     for (const char** imageName = allowedImagery; *imageName != NULL; imageName++)
  1076.     {
  1077.         _allowedAssetMap[*imageName] = true;
  1078.     }
  1079. }
  1080.  
  1081. char lastZoneName[256];
  1082.  
  1083. CallHook loadTextureHook;
  1084. DWORD loadTextureHookLoc = 0x4D32BC;
  1085.  
  1086. static int lastImageTime;
  1087. static __int64 totalImageTime;
  1088.  
  1089. void WriteEndImageProfile()
  1090. {
  1091.     int time = Com_Milliseconds() - lastImageTime;
  1092.     GfxImage* image = *(GfxImage**)0x112AD40;
  1093.  
  1094.     //WriteProfile(Com_Milliseconds(), "image_end", va("%s - %ims", image->name, time));
  1095.  
  1096.     totalImageTime += time;
  1097. }
  1098.  
  1099. bool CanWeLoadThisImage()
  1100. {
  1101.     GfxImage* image = *(GfxImage**)0x112AD40;
  1102.  
  1103.     //WriteProfile(Com_Milliseconds(), "image", image->name);
  1104.     lastImageTime = Com_Milliseconds();
  1105.  
  1106.     if (strcmp(CURRENT_ZONE_NAME, "ui_viewer_mp") != NULL)
  1107.     {
  1108.         return true;
  1109.     }
  1110.  
  1111.     if (_allowedAssetMap.find(image->name) == _allowedAssetMap.end())
  1112.     {
  1113.         return true;
  1114.     }
  1115.  
  1116.     return false;
  1117. }
  1118.  
  1119. void __declspec(naked) Load_TextureHookStub()
  1120. {
  1121.     __asm
  1122.     {
  1123.         call CanWeLoadThisImage
  1124.         test al, al
  1125.         jz justNope
  1126.  
  1127.         mov eax, [esp + 4]
  1128.         mov ecx, [esp + 8]
  1129.         push ecx
  1130.         push eax
  1131.         call loadTextureHook.pOriginal
  1132.         add esp, 8h
  1133.  
  1134.         call WriteEndImageProfile
  1135.  
  1136. justNope:
  1137.         retn
  1138.     }
  1139. }
  1140.  
  1141. /*
  1142. bool FilterImageLoad(GfxImage* image)
  1143. {
  1144.     for (const char** imageName = allowedImagery; *imageName != NULL; imageName++)
  1145.     {
  1146.         if (!strcmp(*imageName, image->name))
  1147.         {
  1148.             return true;
  1149.         }
  1150.     }
  1151.  
  1152.     image->texture = (IDirect3DTexture9*)0xCA3E1337; // will cause oddities if referenced...
  1153.     OutputDebugString(va("%s\n", image->name));
  1154.  
  1155.     return false;
  1156. }
  1157.  
  1158. static char lastZoneName[256];
  1159.  
  1160. CallHook loadTextureHook;
  1161. DWORD loadTextureHookLoc = 0x51F595;
  1162.  
  1163. bool IsImageAllowedToLoad1(GfxImage* image)
  1164. {
  1165.     strcpy(lastZoneName, CURRENT_ZONE_NAME);
  1166.     WriteProfile(Com_Milliseconds(), "image", image->name);
  1167.  
  1168.     return true;
  1169. }
  1170.  
  1171. void __declspec(naked) Load_TextureHookStub()
  1172. {
  1173.     __asm
  1174.     {
  1175.         mov eax, [esp + 4]
  1176.         push eax
  1177.         call IsImageAllowedToLoad1
  1178.         add esp, 4h
  1179.  
  1180.         test al, al
  1181.         jz returnOne
  1182.         jmp loadTextureHook.pOriginal
  1183.  
  1184. returnOne:
  1185.         mov eax, 1
  1186.         retn
  1187.     }
  1188. }*/
  1189.  
  1190. CallHook rDelayLoadImageHook;
  1191. DWORD rDelayLoadImageHookLoc = 0x51F486;
  1192.  
  1193. bool IsImageAllowedToLoad2(GfxImage* image)
  1194. {
  1195.     WriteProfile(Com_Milliseconds(), "image_delay", image->name);
  1196.  
  1197.     return true;
  1198. }
  1199.  
  1200. void __declspec(naked) R_DelayLoadImageHookStub()
  1201. {
  1202.     __asm
  1203.     {
  1204.         mov eax, [esp + 4]
  1205.         push eax
  1206.         call IsImageAllowedToLoad2
  1207.         add esp, 4h
  1208.  
  1209.         test al, al
  1210.         jz returnOne
  1211.         jmp rDelayLoadImageHook.pOriginal
  1212.  
  1213. returnOne:
  1214.         mov eax, 1
  1215.         retn
  1216.     }
  1217. }
  1218.  
  1219. StompHook endLoadZoneHook;
  1220. DWORD endLoadZoneHookLoc = 0x415AC2;
  1221.  
  1222. void EndLoadZoneHookFunc()
  1223. {
  1224.     //WriteProfile(Com_Milliseconds(), "zone_end", lastZoneName);
  1225.     totalImageTime = 0;
  1226. }
  1227.  
  1228. CallHook loadDynEntityDefHook;
  1229. DWORD loadDynEntityDefHookLoc = 0x47CE5F;
  1230.  
  1231. void* LoadDefaultAsset(assetType_t atype);
  1232.  
  1233. void LoadDynEntityDefHookFunc(int arg)
  1234. {
  1235.     if (**(DWORD**)0x112A934 == 0x3F800000)
  1236.     {
  1237.         void** defaultAsset = (void**)LoadDefaultAsset(ASSET_TYPE_XMODEL);
  1238.  
  1239.         **(DWORD**)0x112A934 = (DWORD)(defaultAsset[1]);
  1240.     }
  1241. }
  1242.  
  1243. void __declspec(naked) LoadDynEntityDefHookStub()
  1244. {
  1245.     __asm
  1246.     {
  1247.         push 0
  1248.         call loadDynEntityDefHook.pOriginal
  1249.         add esp, 4h
  1250.  
  1251.         call LoadDynEntityDefHookFunc
  1252.  
  1253.         retn
  1254.     }
  1255. }
  1256.  
  1257. // prevents an infinite loop if the string ID does not exist in some secondary table
  1258. StompHook slFreeStringHook;
  1259. DWORD slFreeStringHookLoc = 0x61BFCC;
  1260. DWORD slFreeStringHookRet = 0x61BFD3;
  1261.  
  1262. DWORD slFreeStringHookZF;
  1263.  
  1264. void __declspec(naked) SL_FreeStringHookStub()
  1265. {
  1266.     __asm
  1267.     {
  1268.         jz setZFZero
  1269.  
  1270.         mov slFreeStringHookZF, 0
  1271.         jmp continueHook
  1272.  
  1273. setZFZero:
  1274.         mov slFreeStringHookZF, 1
  1275.  
  1276. continueHook:
  1277.  
  1278.         lea eax, ds:1DC2280h[ecx * 8]
  1279.         cmp cx, word ptr [eax]
  1280.  
  1281.         je returnToSender
  1282.  
  1283.         /*push eax
  1284.         push ebx
  1285.         mov eax, [eax]
  1286.         mov ebx, eax
  1287.         lea eax, ds:1DC2280h[eax * 8]
  1288.         cmp bx, word ptr [eax]
  1289.         pop ebx
  1290.         pop eax
  1291.  
  1292.         jge returnToSender*/
  1293.  
  1294.         push eax
  1295.         mov eax, slFreeStringHookZF
  1296.         dec eax // will set ZF to 0 if it was 1
  1297.         pop eax
  1298.  
  1299.         jmp slFreeStringHookRet
  1300.  
  1301. returnToSender:
  1302.         push 11h
  1303.         mov eax, 41B8C0h // Sys_LeaveCriticalSection
  1304.         call eax
  1305.         add esp, 4
  1306.         pop esi
  1307.         pop ebp
  1308.         pop ebx
  1309.         retn
  1310.     }
  1311. }
  1312.  
  1313. struct refdef_t
  1314. {
  1315.     int x;
  1316.     int y;
  1317.     int width;
  1318.     int height;
  1319.     float fovX;
  1320.     float fovY;
  1321.     float origin[3];
  1322.     float viewmatrix[3][3];
  1323.     char pad[16200];
  1324.     float viewangles[3];
  1325.     char pad2[1232];
  1326. };
  1327.  
  1328. #include <d3d9.h>
  1329.  
  1330. CallHook renderSceneHook;
  1331. DWORD renderSceneHookLoc = 0x4EB3DB;
  1332.  
  1333. StompHook clearViewportHook1;
  1334. DWORD clearViewportHookLoc1 = 0x555A71;
  1335. DWORD clearViewportHookRet1 = 0x555A76;
  1336.  
  1337. static struct  
  1338. {
  1339.     LONG rect[4];
  1340.     bool active;
  1341. } g_clearViewport;
  1342.  
  1343. LONG* ViewportRectToD3DRect(LONG* rect, IDirect3DDevice9* device)
  1344. {
  1345.     static LONG rects[4][4];
  1346.     static int callNum;
  1347.  
  1348.     int i = (callNum++ % 4);
  1349.     callNum = i;
  1350.  
  1351.     rects[i][0] = rect[0];
  1352.     rects[i][1] = rect[1];
  1353.     rects[i][2] = rect[0] + rect[2];
  1354.     rects[i][3] = rect[1] + rect[3];
  1355.  
  1356.     D3DVIEWPORT9 vp;
  1357.     vp.X = rect[0];
  1358.     vp.Y = rect[1];
  1359.     vp.Width = rect[2];
  1360.     vp.Height = rect[3];
  1361.  
  1362.     vp.MinZ = 0.0f;
  1363.     vp.MaxZ = 1.0f;
  1364.  
  1365.     device->SetViewport(&vp);
  1366.  
  1367.     return rects[i];
  1368. }
  1369.  
  1370. void __declspec(naked) ClearViewportHook1Stub()
  1371. {
  1372.     __asm
  1373.     {
  1374.         push ecx
  1375.  
  1376.         lea eax, [ebp + 336]
  1377.  
  1378.         //push eax
  1379.         push ecx
  1380.         push edx
  1381.         push esi
  1382.         push eax
  1383.         call ViewportRectToD3DRect
  1384.         add esp, 8
  1385.         pop edx
  1386.         pop ecx
  1387.         //add esp, 4h
  1388.  
  1389.         push eax
  1390.  
  1391.         //push offset g_clearViewport.rect
  1392.         push 1
  1393.  
  1394.         jmp clearViewportHookRet1
  1395.     }
  1396. }
  1397.  
  1398. StompHook clearViewportHook2;
  1399. DWORD clearViewportHookLoc2 = 0x555994;
  1400. DWORD clearViewportHookRet2 = 0x55599A;
  1401.  
  1402. void __declspec(naked) ClearViewportHook2Stub()
  1403. {
  1404.     __asm
  1405.     {
  1406.         push 6
  1407.  
  1408.         mov al, g_clearViewport.active
  1409.         test al, al
  1410.  
  1411.         jz returnAsPlanned
  1412.  
  1413.         lea eax, [ebp + 336]
  1414.  
  1415.         push ecx
  1416.         push edx
  1417.         push esi
  1418.         push eax
  1419.         call ViewportRectToD3DRect
  1420.         add esp, 8
  1421.         pop edx
  1422.         pop ecx
  1423.  
  1424.         push eax
  1425.         //push offset g_clearViewport.rect
  1426.         push 1
  1427.  
  1428.         jmp clearViewportHookRet2
  1429.  
  1430. returnAsPlanned:
  1431.         push 0
  1432.         push 0
  1433.         jmp clearViewportHookRet2
  1434.     }
  1435. }
  1436.  
  1437. #define COPY_VIEWPORT(refdef) \
  1438.     g_clearViewport.rect[0] = (refdef)->x; \
  1439.     g_clearViewport.rect[1] = (refdef)->y; \
  1440.     g_clearViewport.rect[2] = (refdef)->x + (refdef)->width; \
  1441.     g_clearViewport.rect[3] = (refdef)->y + (refdef)->height
  1442.  
  1443. void CL_RenderSceneHookFunc(refdef_t* refdef)
  1444. {
  1445.     DWORD rendSync = 0x509500;
  1446.     DWORD issueRenderCommands = 0x509350;
  1447.  
  1448.     g_clearViewport.active = true;
  1449.  
  1450.     refdef->height /= 2;
  1451.     refdef->fovY /= 2;
  1452.  
  1453.     COPY_VIEWPORT(refdef);
  1454.  
  1455.     // and re-enable clearing
  1456.     //*(WORD*)0x555A3F = 0x0575;
  1457.     //*(BYTE*)0x555A44 = 0x74;
  1458.  
  1459.     __asm
  1460.     {
  1461.         push refdef
  1462.         call renderSceneHook.pOriginal
  1463.         add esp, 4h
  1464.  
  1465.         push 1
  1466.         call issueRenderCommands
  1467.         add esp, 4h
  1468.  
  1469.         call rendSync
  1470.     }
  1471.  
  1472.     static refdef_t replacementDef;
  1473.     memcpy(&replacementDef, refdef, sizeof(refdef_t));
  1474.  
  1475.     replacementDef.y += replacementDef.height;
  1476.     replacementDef.origin[2] += 50.0f;
  1477.  
  1478.     replacementDef.viewangles[1] += 30.0f;
  1479.  
  1480.     COPY_VIEWPORT(&replacementDef);
  1481.  
  1482.     // disable clearing the color buffer at this stage (by default; that is - but r_clear generally is unset anyway)
  1483.     //*(WORD*)0x555A3F = 0x9090;
  1484.     //*(BYTE*)0x555A44 = 0xEB;
  1485.  
  1486.     __asm
  1487.     {
  1488.         push offset replacementDef
  1489.         call renderSceneHook.pOriginal
  1490.         add esp, 4h
  1491.  
  1492.         //push 2
  1493.         //call issueRenderCommands
  1494.         //add esp, 4h
  1495.  
  1496.         //call rendSync
  1497.     }
  1498.  
  1499.     *(BYTE*)0x5ACBA9 &= ~1;
  1500.  
  1501.     /*static refdef_t replacementDef2;
  1502.     memcpy(&replacementDef2, refdef, sizeof(refdef_t));
  1503.  
  1504.     replacementDef2.x = 150;
  1505.     replacementDef2.y = 150;
  1506.  
  1507.     replacementDef2.width = 150;
  1508.     replacementDef2.height = 150;
  1509.  
  1510.     replacementDef2.fovX = replacementDef2.fovY;
  1511.  
  1512.     replacementDef2.viewangles[1] += 30.0f;
  1513.  
  1514.     __asm
  1515.     {
  1516.         push offset replacementDef2
  1517.         call renderSceneHook.pOriginal
  1518.         add esp, 4h
  1519.     }*/
  1520. }
  1521.  
  1522. /*CallHook renderSceneHook;
  1523. DWORD renderSceneHookLoc = 0x5ACB79;
  1524.  
  1525. int CL_RenderSceneHookFunc(int clientNum)
  1526. {
  1527.     int retval;
  1528.     DWORD issueRenderCommands = 0x509350;
  1529.  
  1530.     __asm
  1531.     {
  1532.         push 0
  1533.         call renderSceneHook.pOriginal
  1534.         add esp, 4h
  1535.  
  1536.         mov retval, eax
  1537.     }
  1538.  
  1539.     if (retval)
  1540.     {
  1541.         __asm
  1542.         {
  1543.             push 3
  1544.             call issueRenderCommands
  1545.             add esp, 4h
  1546.         }
  1547.  
  1548.         *(BYTE*)0x5ACBA9 &= ~1;
  1549.  
  1550.         int coords[4];
  1551.         memcpy(coords, (int*)0x7ED3B8, 16);
  1552.  
  1553.         int* rCoords = (int*)0x7ED3B8;
  1554.  
  1555.         rCoords[0] = 150;
  1556.         rCoords[1] = 150;
  1557.         rCoords[2] = 300;
  1558.         rCoords[3] = 300;
  1559.  
  1560.         __asm
  1561.         {
  1562.             push 0
  1563.             call renderSceneHook.pOriginal
  1564.             add esp, 4h
  1565.         }
  1566.  
  1567.         memcpy((int*)0x7ED3B8, coords, 16);
  1568.     }
  1569.  
  1570.     return retval;
  1571. }*/
  1572.  
  1573. CallHook logPixelShaderHook;
  1574. DWORD logPixelShaderHookLoc = 0x5B9D48;
  1575.  
  1576. void LogPixelShader()
  1577. {
  1578.     PixelShader* shader = *(PixelShader**)0x112AEF4;
  1579.     MaterialTechniqueSet* techset = *(MaterialTechniqueSet**)0x112AE8C;
  1580.  
  1581.     //WriteProfile(Com_Milliseconds(), "pixelshader", va("%08x - %s (%s)", (DWORD)shader->shader, shader->name, techset->name));
  1582. }
  1583.  
  1584. void __declspec(naked) LogPixelShaderHookStub()
  1585. {
  1586.     __asm
  1587.     {
  1588.         mov eax, [esp + 4]
  1589.         mov ecx, [esp + 8]
  1590.         push ecx
  1591.         push eax
  1592.         call logPixelShaderHook.pOriginal
  1593.         add esp, 8
  1594.  
  1595.         jmp LogPixelShader
  1596.     }
  1597. }
  1598.  
  1599. CallHook logVertexShaderHook;
  1600. DWORD logVertexShaderHookLoc = 0x420BC8;
  1601.  
  1602. void LogVertexShader()
  1603. {
  1604.     VertexShader* shader = *(VertexShader**)0x112B338;
  1605.     MaterialTechniqueSet* techset = *(MaterialTechniqueSet**)0x112AE8C;
  1606.  
  1607.     //WriteProfile(Com_Milliseconds(), "vertexshader", va("%08x - %s (%s)", (DWORD)shader->shader, shader->name, techset->name));
  1608. }
  1609.  
  1610. void __declspec(naked) LogVertexShaderHookStub()
  1611. {
  1612.     __asm
  1613.     {
  1614.         mov eax, [esp + 4]
  1615.         mov ecx, [esp + 8]
  1616.         push ecx
  1617.         push eax
  1618.         call logVertexShaderHook.pOriginal
  1619.         add esp, 8
  1620.  
  1621.         jmp LogVertexShader
  1622.     }
  1623. }
  1624.  
  1625. void PatchMW2_DumpModel();
  1626.  
  1627. void PatchMW2_Experimental()
  1628. {
  1629.     static cmd_function_s sndAliasListCmd;
  1630.     static cmd_function_s dumptyCmd;
  1631.  
  1632.     //psClearHook.initialize(PsClearHookStub);
  1633.     //psClearHook.installHook();
  1634.  
  1635.     weaponFileHook.initialize(weaponFileHookLoc, WeaponFileHookStub);
  1636.     weaponFileHook.installHook();
  1637.  
  1638.     vehicleFileHook.initialize(vehicleFileHookLoc, VehicleFileHookFunc);
  1639.     vehicleFileHook.installHook();
  1640.  
  1641.     addEntryNameHook.initialize(addEntryNameHookLoc, AddEntryNameHookStub);
  1642.     addEntryNameHook.installHook();
  1643.  
  1644.     modelOverflowHook.initialize(modelOverflowHookLoc, ModelOverflowHookStub);
  1645.     modelOverflowHook.installHook();
  1646.  
  1647.     InitializeImageLoad();
  1648.  
  1649.     loadTextureHook.initialize(loadTextureHookLoc, Load_TextureHookStub);
  1650.     loadTextureHook.installHook();
  1651.  
  1652.     rDelayLoadImageHook.initialize(rDelayLoadImageHookLoc, R_DelayLoadImageHookStub);
  1653.     rDelayLoadImageHook.installHook();
  1654.  
  1655.     endLoadZoneHook.initialize(endLoadZoneHookLoc, EndLoadZoneHookFunc);
  1656.     endLoadZoneHook.installHook();
  1657.  
  1658.     Cmd_AddCommand("meh", MehFunc, &mehCmd, 0);
  1659.     Cmd_AddCommand("snd_alias_list_t", SndAliasListFunc, &sndAliasListCmd, 0);
  1660.     Cmd_AddCommand("dumptydump", DumpRawFiles, &dumptyCmd, 0);
  1661.  
  1662.     loadDynEntityDefHook.initialize(loadDynEntityDefHookLoc, LoadDynEntityDefHookStub);
  1663.     loadDynEntityDefHook.installHook();
  1664.  
  1665.     //slFreeStringHook.initialize(slFreeStringHookLoc, SL_FreeStringHookStub);
  1666.     //slFreeStringHook.installHook();
  1667.  
  1668.     logPixelShaderHook.initialize(logPixelShaderHookLoc, LogPixelShaderHookStub);
  1669.     logPixelShaderHook.installHook();
  1670.  
  1671.     logVertexShaderHook.initialize(logVertexShaderHookLoc, LogVertexShaderHookStub);
  1672.     logVertexShaderHook.installHook();
  1673.  
  1674.     /*renderSceneHook.initialize(renderSceneHookLoc, CL_RenderSceneHookFunc);
  1675.     renderSceneHook.installHook();
  1676.  
  1677.     clearViewportHook1.initialize(clearViewportHookLoc1, ClearViewportHook1Stub);
  1678.     clearViewportHook1.installHook();
  1679.  
  1680.     clearViewportHook2.initialize(clearViewportHookLoc2, ClearViewportHook2Stub);
  1681.     clearViewportHook2.installHook();*/
  1682.  
  1683.     //endLoadingHook.initialize(endLoadingHookLoc, EndLoadingHookStub);
  1684.     //endLoadingHook.installHook();
  1685.  
  1686.     //scriptOddLogHook.initialize(scriptOddLogHookLoc, ScriptOddLogHookStub);
  1687.     //scriptOddLogHook.installHook();
  1688.  
  1689.     //scriptOddLogHook2.initialize(scriptOddLogHook2Loc, ScriptOddLogHook2Stub);
  1690.     //scriptOddLogHook2.installHook();
  1691.  
  1692.     // BAD HACK: load any weapon without cache in G_GetWeaponByName
  1693.     // wow, this was needed in T5 as well. wonder why.
  1694.     // (nope, didn't fix it)
  1695.     //*(WORD*)0x43DF17 = 0x9090;
  1696.  
  1697.     // allow fs_debug open prints from other threads
  1698.     *(WORD*)0x643787 = 0x9090;
  1699.     *(WORD*)0x64357F = 0x9090;
  1700.  
  1701.     PatchMW2_DumpModel();
  1702. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement