Skip to content

Commit 2b0a3c6

Browse files
committed
MW3 OBJ fix & COD4 SP support
1 parent 8c6cd14 commit 2b0a3c6

File tree

4 files changed

+123
-118
lines changed

4 files changed

+123
-118
lines changed

src/Husky/Husky/Games/ModernWarfare3.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,14 @@ public static void ExportBSPData(ProcessReader reader, long assetPoolsAddress, l
271271
// Create new OBJ
272272
var obj = new WavefrontOBJ();
273273

274+
// Append Vertex Data
275+
foreach (var vertex in vertices)
276+
{
277+
obj.Vertices.Add(vertex.Position);
278+
obj.Normals.Add(vertex.Normal);
279+
obj.UVs.Add(vertex.UV);
280+
}
281+
274282
// Image Names (for Search String)
275283
HashSet<string> imageNames = new HashSet<string>();
276284

@@ -436,7 +444,7 @@ public static WavefrontOBJ.Material ReadMaterial(ProcessReader reader, long addr
436444
var materialImage = reader.ReadStruct<MaterialImage32B>(material.ImageTablePointer + i * Marshal.SizeOf<MaterialImage32B>());
437445
// Check for color map for now
438446
if (materialImage.SemanticHash == 0xA0AB1041)
439-
objMaterial.DiffuseMap = "_images\\\\" + reader.ReadNullTerminatedString(reader.ReadInt32(materialImage.ImagePointer + 0x1C)) + ".png";
447+
objMaterial.DiffuseMap = "_images\\\\" + reader.ReadNullTerminatedString(reader.ReadInt32(materialImage.ImagePointer + 0x1C));
440448
}
441449
// Done
442450
return objMaterial;

src/Husky/Husky/HuskyUtil.cs

Lines changed: 110 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,110 @@
1-
// ------------------------------------------------------------------------
2-
// Husky - Call of Duty BSP Extractor
3-
// Copyright (C) 2018 Philip/Scobalula
4-
//
5-
// This program is free software: you can redistribute it and/or modify
6-
// it under the terms of the GNU General Public License as published by
7-
// the Free Software Foundation, either version 3 of the License, or
8-
// (at your option) any later version.
9-
10-
// This program is distributed in the hope that it will be useful,
11-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13-
// GNU General Public License for more details.
14-
15-
// You should have received a copy of the GNU General Public License
16-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17-
// ------------------------------------------------------------------------
18-
// TODO: Write converters for other formats (like SEModel) for now we're just writing OBJ
19-
using System;
20-
using System.Collections.Generic;
21-
using System.Diagnostics;
22-
using System.IO;
23-
using System.Reflection;
24-
using PhilLibX;
25-
using PhilLibX.IO;
26-
27-
namespace Husky
28-
{
29-
/// <summary>
30-
/// Game Definition (AssetDB Address, Sizes Address, Game Type ID (MP, SP, ZM, etc.), Export Method
31-
/// </summary>
32-
using GameDefinition = Tuple<long, long, string, Action<ProcessReader, long, long, string, Action<object>>>;
33-
34-
/// <summary>
35-
/// Main Program Class
36-
/// </summary>
37-
public class HuskyUtil
38-
{
39-
/// <summary>
40-
/// Game Addresses & Methods (Asset DB and Asset Pool Sizes) (Some are relative due to ASLR)
41-
/// </summary>
42-
static readonly Dictionary<string, GameDefinition> Games = new Dictionary<string, GameDefinition>()
43-
{
44-
// Call of Duty: World At War
45-
{ "CoDWaWmp", new GameDefinition(0x8D0958, 0x8D06E8, "mp", WorldatWar.ExportBSPData) },
46-
{ "CoDWaW", new GameDefinition(0x8DC828, 0x8DC5D0, "sp", WorldatWar.ExportBSPData) },
47-
// Call of Duty: Modern Warfare
48-
{ "iw3mp", new GameDefinition(0x7265E0, 0x7263A0, "mp", ModernWarfare.ExportBSPData) },
49-
{ "iw3sp", new GameDefinition(0x7307F8, 0x730510, "sp", ModernWarfare.ExportBSPData) },
50-
// Call of Duty: Modern Warfare 2
51-
{ "iw4mp", new GameDefinition(0x6F81D0, 0x6F7F08, "mp", ModernWarfare2.ExportBSPData) },
52-
{ "iw4sp", new GameDefinition(0x7307F8, 0x730510, "sp", ModernWarfare2.ExportBSPData) },
53-
// Call of Duty: Modern Warfare 3
54-
{ "iw5mp", new GameDefinition(0x8AB258, 0x8AAF78, "mp", ModernWarfare3.ExportBSPData) },
55-
{ "iw5sp", new GameDefinition(0x92AD20, 0x92AA40, "sp", ModernWarfare3.ExportBSPData) },
56-
// Call of Duty: Black Ops
57-
{ "BlackOps", new GameDefinition(0xB741B8, 0xB73EF8, "sp", BlackOps.ExportBSPData) },
58-
{ "BlackOpsMP", new GameDefinition(0xBF2C30, 0xBF2970, "mp", BlackOps.ExportBSPData) },
59-
// Call of Duty: Black Ops 2
60-
{ "t6zm", new GameDefinition(0xD41240, 0xD40E80, "zm", BlackOps2.ExportBSPData) },
61-
{ "t6mp", new GameDefinition(0xD4B340, 0xD4AF80, "mp", BlackOps2.ExportBSPData) },
62-
{ "t6sp", new GameDefinition(0xBD46B8, 0xBD42F8, "sp", BlackOps2.ExportBSPData) },
63-
// Call of Duty: Ghosts
64-
{ "iw6mp64_ship", new GameDefinition(0x1409E4F20, 0x1409E4E20, "mp", Ghosts.ExportBSPData) },
65-
{ "iw6sp64_ship", new GameDefinition(0x14086DCB0, 0x14086DBB0, "sp", Ghosts.ExportBSPData) },
66-
// Call of Duty: Infinite Warfare
67-
{ "iw7_ship", new GameDefinition(0x1414663D0, 0x141466290, "core", InfiniteWarfare.ExportBSPData) },
68-
// Call of Duty: Advanced Warfare
69-
{ "s1_mp64_ship", new GameDefinition(0x1409B40D0, 0x1409B4B90, "mp", AdvancedWarfare.ExportBSPData) },
70-
{ "s1_sp64_ship", new GameDefinition(0x140804690, 0x140804140, "sp", AdvancedWarfare.ExportBSPData) },
71-
// Call of Duty: World War II
72-
{ "s2_mp64_ship", new GameDefinition(0xC05370, 0xC05370, "mp", WorldWarII.ExportBSPData) },
73-
{ "s2_sp64_ship", new GameDefinition(0x9483F0, 0xBCC5E0, "sp", WorldWarII.ExportBSPData) },
74-
// Call of Duty: Modern Warfare Remastered
75-
{ "h1_mp64_ship", new GameDefinition(0x10B4460, 0x10B3C80, "mp", ModernWarfareRM.ExportBSPData) },
76-
{ "h1_sp64_ship", new GameDefinition(0xEC9FB0, 0xEC97D0, "sp", ModernWarfareRM.ExportBSPData) },
77-
};
78-
79-
/// <summary>
80-
/// Looks for matching game and loads BSP from it
81-
/// </summary>
82-
public static void LoadGame(Action<object> printCallback = null)
83-
{
84-
try
85-
{
86-
// Get all processes
87-
var processes = Process.GetProcesses();
88-
89-
// Loop through them, find match
90-
foreach (var process in processes)
91-
{
92-
// Check for it in dictionary
93-
if (Games.TryGetValue(process.ProcessName, out var game))
94-
{
95-
// Export it
96-
game.Item4(new ProcessReader(process), game.Item1, game.Item2, game.Item3, printCallback);
97-
98-
// Done
99-
return;
100-
}
101-
}
102-
103-
// Failed
104-
printCallback?.Invoke("Failed to find a supported game, please ensure one of them is running.");
105-
}
106-
catch(Exception e)
107-
{
108-
printCallback?.Invoke("An unhandled exception has occured:");
109-
printCallback?.Invoke(e);
110-
}
111-
}
112-
}
113-
}
1+
// ------------------------------------------------------------------------
2+
// Husky - Call of Duty BSP Extractor
3+
// Copyright (C) 2018 Philip/Scobalula
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
// ------------------------------------------------------------------------
18+
// TODO: Write converters for other formats (like SEModel) for now we're just writing OBJ
19+
using System;
20+
using System.Collections.Generic;
21+
using System.Diagnostics;
22+
using System.IO;
23+
using PhilLibX.IO;
24+
25+
namespace Husky
26+
{
27+
/// <summary>
28+
/// Game Definition (AssetDB Address, Sizes Address, Game Type ID (MP, SP, ZM, etc.), Export Method
29+
/// </summary>
30+
using GameDefinition = Tuple<long, long, string, Action<ProcessReader, long, long, string, Action<object>>>;
31+
32+
/// <summary>
33+
/// Main Program Class
34+
/// </summary>
35+
public class HuskyUtil
36+
{
37+
/// <summary>
38+
/// Game Addresses & Methods (Asset DB and Asset Pool Sizes) (Some are relative due to ASLR)
39+
/// </summary>
40+
static readonly Dictionary<string, GameDefinition> Games = new Dictionary<string, GameDefinition>()
41+
{
42+
// Call of Duty: World At War
43+
{ "CoDWaWmp", new GameDefinition(0x8D0958, 0x8D06E8, "mp", WorldatWar.ExportBSPData) },
44+
{ "CoDWaW", new GameDefinition(0x8DC828, 0x8DC5D0, "sp", WorldatWar.ExportBSPData) },
45+
// Call of Duty: Modern Warfare
46+
{ "iw3mp", new GameDefinition(0x7265E0, 0x7263A0, "mp", ModernWarfare.ExportBSPData) },
47+
{ "iw3sp", new GameDefinition(0x6DF200, 0x730510, "sp", ModernWarfare.ExportBSPData) },
48+
// Call of Duty: Modern Warfare 2
49+
{ "iw4mp", new GameDefinition(0x6F81D0, 0x6F7F08, "mp", ModernWarfare2.ExportBSPData) },
50+
{ "iw4sp", new GameDefinition(0x7307F8, 0x730510, "sp", ModernWarfare2.ExportBSPData) },
51+
// Call of Duty: Modern Warfare 3
52+
{ "iw5mp", new GameDefinition(0x8AB258, 0x8AAF78, "mp", ModernWarfare3.ExportBSPData) },
53+
{ "iw5sp", new GameDefinition(0x92AD20, 0x92AA40, "sp", ModernWarfare3.ExportBSPData) },
54+
// Call of Duty: Black Ops
55+
{ "BlackOps", new GameDefinition(0xB741B8, 0xB73EF8, "sp", BlackOps.ExportBSPData) },
56+
{ "BlackOpsMP", new GameDefinition(0xBF2C30, 0xBF2970, "mp", BlackOps.ExportBSPData) },
57+
// Call of Duty: Black Ops 2
58+
{ "t6zm", new GameDefinition(0xD41240, 0xD40E80, "zm", BlackOps2.ExportBSPData) },
59+
{ "t6mp", new GameDefinition(0xD4B340, 0xD4AF80, "mp", BlackOps2.ExportBSPData) },
60+
{ "t6sp", new GameDefinition(0xBD46B8, 0xBD42F8, "sp", BlackOps2.ExportBSPData) },
61+
// Call of Duty: Ghosts
62+
{ "iw6mp64_ship", new GameDefinition(0x1409E4F20, 0x1409E4E20, "mp", Ghosts.ExportBSPData) },
63+
{ "iw6sp64_ship", new GameDefinition(0x14086DCB0, 0x14086DBB0, "sp", Ghosts.ExportBSPData) },
64+
// Call of Duty: Infinite Warfare
65+
{ "iw7_ship", new GameDefinition(0x1414663D0, 0x141466290, "core", InfiniteWarfare.ExportBSPData) },
66+
// Call of Duty: Advanced Warfare
67+
{ "s1_mp64_ship", new GameDefinition(0x1409B40D0, 0x1409B4B90, "mp", AdvancedWarfare.ExportBSPData) },
68+
{ "s1_sp64_ship", new GameDefinition(0x140804690, 0x140804140, "sp", AdvancedWarfare.ExportBSPData) },
69+
// Call of Duty: World War II
70+
{ "s2_mp64_ship", new GameDefinition(0xC05370, 0xC05370, "mp", WorldWarII.ExportBSPData) },
71+
{ "s2_sp64_ship", new GameDefinition(0x9483F0, 0xBCC5E0, "sp", WorldWarII.ExportBSPData) },
72+
// Call of Duty: Modern Warfare Remastered
73+
{ "h1_mp64_ship", new GameDefinition(0x10B4460, 0x10B3C80, "mp", ModernWarfareRM.ExportBSPData) },
74+
{ "h1_sp64_ship", new GameDefinition(0xEC9FB0, 0xEC97D0, "sp", ModernWarfareRM.ExportBSPData) },
75+
};
76+
77+
/// <summary>
78+
/// Looks for matching game and loads BSP from it
79+
/// </summary>
80+
public static void LoadGame(Action<object> printCallback = null)
81+
{
82+
try
83+
{
84+
// Get all processes
85+
var processes = Process.GetProcesses();
86+
87+
// Loop through them, find match
88+
foreach (var process in processes)
89+
{
90+
// Check for it in dictionary
91+
if (Games.TryGetValue(process.ProcessName, out var game))
92+
{
93+
// Export it
94+
game.Item4(new ProcessReader(process), game.Item1, game.Item2, game.Item3, printCallback);
95+
// Done
96+
return;
97+
}
98+
}
99+
100+
// Failed
101+
printCallback?.Invoke("Failed to find a supported game, please ensure one of them is running.");
102+
}
103+
catch(Exception e)
104+
{
105+
printCallback?.Invoke("An unhandled exception has occured:");
106+
printCallback?.Invoke(e);
107+
}
108+
}
109+
}
110+
}

src/Husky/Husky/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
// You can specify all the values or you can default the Build and Revision Numbers
3232
// by using the '*' as shown below:
3333
// [assembly: AssemblyVersion("1.0.*")]
34-
[assembly: AssemblyVersion("1.0.3.6")]
35-
[assembly: AssemblyFileVersion("1.0.3.6")]
34+
[assembly: AssemblyVersion("1.0.4.2")]
35+
[assembly: AssemblyFileVersion("1.0.4.2")]

src/Husky/HuskyUI/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@
4949
// You can specify all the values or you can default the Build and Revision Numbers
5050
// by using the '*' as shown below:
5151
// [assembly: AssemblyVersion("1.0.*")]
52-
[assembly: AssemblyVersion("1.0.3.6")]
53-
[assembly: AssemblyFileVersion("1.0.3.6")]
52+
[assembly: AssemblyVersion("1.0.4.2")]
53+
[assembly: AssemblyFileVersion("1.0.4.2")]

0 commit comments

Comments
 (0)