KasperZERO

Map magic and solving pointers

15 posts in this topic

To anyone if you can help, how can I properly import weap or scen tags into my Xbox map?

 

I use HHT to recursively import shotgun.weap into my b30 cache file, but I don't know how to get it into the map from there. If anyone could explain this to me that I can get it working I'd appreciate it very much.

Edited by KasperZERO

Share this post


Link to post
Share on other sites

Tiddy-bits:

To use a newly imported tag, you need to reference it. It appears HHT has a dependency swapper, so what I'd do is go into the scenario tag using the dependency swapper and swap a weap reference with your shotgun tag. There are other types of tags that can also be swapped for a weapon without crashing - eqip, scen, and proj tags.

 

I don't mod Halo on Xbox, nor have I used HHT, so back your stuff up before listening to me.

Share this post


Link to post
Share on other sites
18 minutes ago, KasperZERO said:

I'm trying to create a new instance though without swapping ...

Then for weapons, you'll then need a new ITMC tag to reference it, and then swap out a redundant ITMC tag referenced in the scenario tag for your new one. Then find the instance in your scenario editor (Spark Edit?), move the weapon to where you want it, and duplicate the weapon it replaced to restore the original spawn point.

 

If you can use Spark Edit with Xbox maps, then adding a new scenery item is a lot easier than doing so with a weapon. Go to Tools I believe, select "Import Tag Into Scenario", import the tag you added to the map, select a scenery item to duplicate, and then swap it for your new one in the dropdown on the right. If you can't use Spark Edit, then you'll have to follow the same process as you have to do for weapons, sans the ITMC tag.


Oddly, this is familiar to you... as if from an old dream.  

Share this post


Link to post
Share on other sites
29 minutes ago, Tucker933 said:

Then for weapons, you'll then need a new ITMC tag to reference it, and then swap out a redundant ITMC tag referenced in the scenario tag. Then find the instance in your scenario editor (Spark Edit?), move the weapon to where you want it, and duplicate the weapon it replaced to restore the original spawn point.

 

If you can use Spark Edit with Xbox maps, then adding a new scenery item is a lot easier than doing so with a weapon. Go to Tools I believe, select "Import Tag Into Scenario", import the tag you added to the map, select a scenery item to duplicate, and then swap it for your new one in the dropdown on the right. If you can't use Spark Edit, then you'll have to follow the same process as you have to do for weapons, sans the ITMC tag.

From what it looks like, the OP is trying to modify a single player map (b30). Single player maps do not pick items from itmc tags to spawn but rather directly spawn them (thus they don't have a respawn time). There is no way to use an itmc tag, as Halo does not read from the netgame equipment list when a map is loaded in single player mode, and you can see this for yourself by using 'map_name bloodgulch' in Halo (it'll load Blood Gulch but no weapons will spawn).

 

The OP also does not want to swap things out but actually add items in. There are a few ways I can think of that can do this:

  • Use a hex editor to copy the weapons spawn list chunk to the end of the map file. This is a very dirty method and if you add any new tags after this, you risk corrupting your map file. However, this method requires only a hex editor and a set of Eschaton plugins so you can find your way around.
     
  • Extract the tag, use a hex editor to copy the weapons spawn list chunk to the end of the tag file, then reimport it. If you reimport a scenario tag to the end of the tag array, it will not work unless you change the scenario tag ID in the tag data header to the new scenario tag ID, so you will need to do this as well. Unlike method #1, you can continue to add tags without corrupting your map file, but it's a lot more time consuming, and you are trusting whatever is rebuilding your map file to not break things.
     
  • Use the Halo Editing Kit. This is technically the best way to do it, but you will need to decompile your scenario tag into the Guerilla format, edit it with Sapien or Guerilla, then recompile with tool. I don't know how to decompile Xbox maps but I have heard HEK+ can decompile Custom Edition maps, so maybe it can decompile Xbox maps? I don't know.

 

I did write a tool a while back that can do this without recompiling, utilizing my Tritium library, but it's only for Mac, and I only wrote it because Mac users don't have Guerilla. Consequently, it's not released here.

Takka and WaeV like this

Share this post


Link to post
Share on other sites

Ah, on phone so I hadn't checked OP in a while. Though am aware he was trying to add new items rather than swap. =p

 

So ignore my post lol as it only pertains to adding new content for MP maps.

Kavawuvi likes this

Oddly, this is familiar to you... as if from an old dream.  

Share this post


Link to post
Share on other sites
21 hours ago, 002 said:
  • Use a hex editor to copy the weapons spawn list chunk to the end of the map file. This is a very dirty method and if you add any new tags after this, you risk corrupting your map file. However, this method requires only a hex editor and a set of Eschaton plugins so you can find your way around.
     
  • Extract the tag, use a hex editor to copy the weapons spawn list chunk to the end of the tag file, then reimport it. If you reimport a scenario tag to the end of the tag array, it will not work unless you change the scenario tag ID in the tag data header to the new scenario tag ID, so you will need to do this as well. Unlike method #1, you can continue to add tags without corrupting your map file, but it's a lot more time consuming, and you are trusting whatever is rebuilding your map file to not break things.

 

 

I appreciate the information. Could you just explain a bit further about the weapon spawn list chunk, where it is, how to identify it, if it has a header .. but if I add tags or reimport my scnr tag under a new ID, would I need to rereference any addresses that are now changed?

Share this post


Link to post
Share on other sites
9 hours ago, KasperZERO said:

Could you just explain a bit further about the weapon spawn list chunk, where it is, how to identify it, if it has a header

 

Finding a lot of this stuff is pretty simple if you know how to do this. First of all, download Eschaton:

Eschaton 0.8.1, to my knowledge, can't edit Xbox maps, but the plugins should still be relevant. You can find them in Plugins, and I recommend using Sparky's plugins.

 

Since we're editing the scenario tag, we'll want scnr.ent. Go to Eschaton -> Plugins -> Sparky's Plugins and open scnr.ent in a text editor. If you use notepad++ or Atom, you can set the syntax highlighting to XML. Next, in your text editor, search for Weapons. You'll find these two struct definitions:

 

<struct name="Weapons" note="" info="" info_img="" offset="0x270" visible="true" size="92">
	<index name="Type" note="" info="" info_img="" offset="0x00" reflexive="main:Weapon Palette" visible="true"/>
	<index name="Name" note="" info="" info_img="" offset="0x02" reflexive="main:Object Names" visible="true"/>
	
	<bitmask32 name="Not Placed" note="" info="" info_img="" offset="0x04" visible="true">
		<option name="Automatically" value="31"/>
		<option name="On Easy" value="30"/>
		<option name="On Normal" value="29"/>
		<option name="On Hard" value="28"/>
	</bitmask32>

	<short name="Desired Permutation" note="" info="if non-zero, will try to use model permutations which end in this number, eg. '7' would pick 'body-7' and 'head-7'" info_img="" offset="0x06" visible="true"/>

	<float name="Position: x" note="" info="" info_img="" offset="0x08" visible="true"/>
	<float name="Position: y" note="" info="" info_img="" offset="0x0C" visible="true"/>
	<float name="Position: z" note="" info="" info_img="" offset="0x10" visible="true"/>
	<float name="Rotation: y" note="yaw; radians" info="" info_img="" offset="0x14" visible="true"/>
	<float name="Rotation: p" note="pitch; radians" info="" info_img="" offset="0x18" visible="true"/>
	<float name="Rotation: r" note="roll; radians" info="" info_img="" offset="0x1C" visible="true"/>

	<short name="Rounds Left" note="" info="" info_img="" offset="0x48" visible="true"/>
	<short name="Rounds Loaded" note="" info="" info_img="" offset="0x4A" visible="true"/>

	<bitmask32 name="Miscellaneous Flags" note="" info="" info_img="" offset="0x4C" visible="true">
		<option name="Initially at Rest" note="" info="Doesn't Fall" info_img="" value="31"/>
		<option name="Obsolete" value="30"/>
		<option name="Does Accelerate" note="" info="Moves Due to Explosions" info_img="" value="29"/>
	</bitmask32>
</struct>

<struct name="Weapon Palette" note="" info="" info_img="" offset="0x27C" visible="true" size="48">
	<dependency name="Name" note="" info="" info_img="" offset="0x00" visible="true"/>
</struct>

To identify the location of a struct, look at "offset" which is the offset from the beginning of the struct it is in (in this case, the tag). Then to identify how big the struct is, look at size, which is the number of bytes each chunk is.

 

First of all, to find the location of the struct, you'll need to find the offset to the tag. Since you're modifying the scenario tag on a stock map, it'll probably be the first tag, so you'll look for the first tag index in the tag array. To find the tag array, we need to find the tag data header. To find the tag data header, we'll need to look at the cache file header. You'll want to open your map in a hex editor from here. I use HxD, so that's what I'll be screenshotting (I don't have Xbox b30.map so I'll be using Halo PC b30.map, but the process is similar as long as your map file is decompressed).

 

The offset to the tag data header offset is at 0x10 in the cache file header. On my screenshot, you'll see the bytes EC 95 7C 01, but yours will be different. All data is little endian in cache files as it's fed directly into memory (hence the name cache file), so this equals 0x017C95EC.

 

zoTocAS.png

 

To make resolving pointers by hand easier, take that offset and subtract it from the address to where Halo loads tag data into memory and write that value down. On Halo PC, this address is 0x40440000, but on Xbox, it's 0x803A0300 (I think? If it's not, let me know and I'll show you how you can find it). Because I'm modifying Halo PC, I subtract 0x17C95EC from 0x40440000, and this gets me 0x3EC76A14. You can use Google to do this.

 

Anyway, go to the offset you just found and you'll see something that looks like this.

 

ewnqaMJ.png

 

Look for the bytes 72 6E 63 73 (rncs, or scnr backwards).

 

Now go 0x10 bytes from there. In this screenshot, you'll see the value 0x4048CDBC (BC CD 48 40). Take that and subtract our magic number to convert it to an offset.

 

Hmr3Tjs.png

 

In my case, 0x4048CDBC - 0x3EC76A14 = 0x18163A8. This puts me right at the top of the scenario tag.

 

ZkCsJSy.png

 

To get the Weapons struct header, I'd add 0x270 to that. To find the Weapon Palette header, I'd add 0x27C instead of to that. The "header" to these reflexives/structs are only 12 characters long and consists of a count followed by a pointer followed by four unused bytes.

uint32_t count; // 0x0 - number of objects
void *address; // 0x4 - address of objects (subtract our magic number from this value to find the offset)
char unused[4]; // 0x8 - unused

 

9 hours ago, KasperZERO said:

but if I add tags or reimport my scnr tag under a new ID, would I need to rereference any addresses that are now changed?

 

If you import a tag and your new chunks are adjacent to your scenario tag, you will not need to do anything.

 

If you import your scenario tag and your new chunks are adjacent to your scenario tag, you will only need to change the scenario tag ID in the tag data header. This is offset 0x4 from the beginning of the tag data header.

 

If you import a tag and your chunks are not adjacent to your scenario tag, you may have to change the address to the new address manually.

 

KasperZERO and WaeV like this

Share this post


Link to post
Share on other sites
On 2017-06-12 at 0:26 AM, 002 said:

 

To make resolving pointers by hand easier, take that offset and subtract it from the address to where Halo loads tag data into memory and write that value down. On Halo PC, this address is 0x40440000, but on Xbox, it's 0x803A0300 (I think? If it's not, let me know and I'll show you how you can find it). Because I'm modifying Halo PC, I subtract 0x17C95EC from 0x40440000, and this gets me 0x3EC76A14. You can use Google to do this.

 

Anyway, go to the offset you just found and you'll see something that looks like this.

 

ewnqaMJ.png

 

Look for the bytes 72 6E 63 73 (rncs, or scnr backwards).

 

Now go 0x10 bytes from there. In this screenshot, you'll see the value 0x4048CDBC (BC CD 48 40). Take that and subtract our magic number to convert it to an offset.

 

Hmr3Tjs.png

 

 

The number I'm getting [what you had as 0x4048cdbc] is much smaller for me, to the effect of 0x08934f8f .. if I subtract that magic number I'm in negative .. is there a way you could explain how you found that magic number also? Where is this memory address? [not the cache file ...]

Share this post


Link to post
Share on other sites
  • Recently Browsing   0 members

    No registered users viewing this page.