View previous topic :: View next topic |
Author |
Message |
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Sun Mar 24, 2013 1:58 pm Post subject: Is it possible to block texture rendering code? |
|
|
I've fairly new to the Cheat Engine. I've used it over the past few months to find values to fix the now defunct Model 2 Emulator and it's been invaluable for that. Now I've moved on to upgrading Outrun 2006.
The game has held up fairly well over the years with the HUD being the one glaring exception. First off, even though the game supports very high resolutions, the hud seems to render at 480i. Also it stretches to match the screen resolution when you run the game in a widescreen resolution, which isn't too bad if you are running it at 16:9, but if you are running it on a racing sim or ect it just looks awful.
So I'm trying to re do a lot of the hud in 1080p and inject it into the game. I found various texture rippers and managed to get the textures out. I even found a utility called u-mod that allows me to put hack the textures back in at runtime but either umod or the game itself doesn't like texture resizing because if I changed the dimensions of the sprite sheets at all, even by a single pixel, they don't show up in-game.
I know the cheat engine can do a d3d hook and that it can render things to the screen. I'm wondering if there would be an easy way to detect when specific d3d rendering functions are called, run them through a case statement and then replace certain calls (depending upon the texture sent along with the call) with my own. That way I could just load my own textures upon startup and when the game goes to render it's own to the hud, I could just ignore them and use my own high def textures with the properly adjusted aspect ratio.
Of course another method might be to simply decrypt the textures from the game directory, but I haven't had much luck there either. They are all in some sort of container (.sz extension, and nope, it's not szip afaict) and I can't extract them.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25295 Location: The netherlands
|
Posted: Sun Mar 24, 2013 2:46 pm Post subject: |
|
|
The old ce 5.6 has a d3dhook where you can cycle through all textures and mark textures so the objects that use it don't show the texture, which can be reprogrammed easily to skip rendering objects completely. (The 5.6 branch is stored specially in the svn )
There's currently no feature build into the current ce to allow any of this, but i might look into it
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Sun Mar 24, 2013 4:55 pm Post subject: |
|
|
Thanks for the help. I'll look into the 5.6 build.
I would rather have the game still control the rendering of the textures (there's some complex animation that occasionally goes on) but that might be enough to fix the basic parts of the hud that are always on screen.
|
|
Back to top |
|
|
Gniarf Grandmaster Cheater Supreme Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Mon Mar 25, 2013 12:16 pm Post subject: |
|
|
.sz files are just a big zlibbed chunk (remember: "an x marks the spot"). Once you uncompress them you get a few bytes followed by the string "XPR0" or "DDS".
XPR0 marks the beginning of an .xbx (XBoX image) file.
DDS, marks the beginning of a .dds file.
It seems the game needs the .sz to be recompressed to read them, so you'll need a generic zlib unpacker AND repacker. There must be tons of them on the net. "offzip -a file.sz output_dir 0" can do the unpacking part.
Repacking must be done with compression level=9=Z_BEST_COMPRESSION otherwise the game won't accept it (wtf?).
Judging from the .dds I saw, they are stored top down, mirrored left-right.
I've tried replacing the .dds with one of my own (of the same size) and repacking that, but the game didn't like it: I get a black screen. That must have something to do with the few bytes at the beginning. And given the other projects I have atm, I not going to investigate this any further. One tip I can give you though: in the uncompressed .sz, bytes 4 to 7 (0 based) hold the size of the .dds/.xbx payload, in small endian.
|
|
Back to top |
|
|
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Tue Mar 26, 2013 3:25 am Post subject: |
|
|
That is extremely helpful, thanks.
In addition to the compressed texture files, there are also compressed files in the "sprani" folder that control the sprite sheet offsets, animation effects, and ect.... my guess is I'll also have to edit these files which won't be terribly hard now that I can actually get to them.
|
|
Back to top |
|
|
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Wed Mar 27, 2013 2:29 am Post subject: |
|
|
I just wanted to say thanks again.
I'm currently busy with other stuff, but I've already written a little utility that takes offzip, decompresses the file chunk and them attempts to part out the individual files (only xtx and dds atm). Once I get some time I'll look into the header format and see about packing things back up.
You can follow my progress over at byoac (sorry can't post urls yet).
|
|
Back to top |
|
|
Gniarf Grandmaster Cheater Supreme Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Wed Mar 27, 2013 8:51 am Post subject: |
|
|
Actually I've already been watching you at http://forum.arcadecontrols.com/index.php?topic=130891.40 for a few days.
Just one thought though: you published your tool in the hope that some might help you reverse the header format, but as a reverser it would be good to have the unzlibbed chunk available as a single file in addition to the extracted .dds/.xbx because it makes it easier to look for payload start offsets. With separate files I don't know in which order they are supposed to be in the - let's call it a .suz: Sumo UnZlibbed - so I can't rebuild it to figure that out.
I am not affected by this for obvious reasons, but I'm not sure the average hex editing guy is going to manually unzlib the .sz to study the header.
Note: I didn't try your extractor, so maybe you already implemented the above suggestion, in which case, just ignore this post.
|
|
Back to top |
|
|
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Thu Mar 28, 2013 12:36 pm Post subject: |
|
|
Yeah I'll add that in as an option. If anything for my own benefit. I was trying to look into it and having to fire up the command line with oddly named files like that is a pain in the butt.
I've added re-packing support as well. I'll also add a file padding function.... at least until the header figured out.
On that note there appear to be different file types with different headers. When offzip decompresses them, the files have different extensions.... thus far I've seen .bin, .dat, .lib and .nfs Texture packages almost always have a .dat extension.
|
|
Back to top |
|
|
Gniarf Grandmaster Cheater Supreme Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Mar 29, 2013 12:47 pm Post subject: |
|
|
Firstly I'll now use ".suz" (S? UnZlibbed) to designate unzlibbed .sz files. I think that obj_*.suz files have a different format that spr_*.suz. I needed to take a break off my other projects yesterday, so I found part of the format the obj_*.suz use:
Code: | #include "standard-types.hsl"
#pragma displayname("Outrun 2006 SUZ files") ;
#pragma byteorder(little_endian)
typedef DWORD uint ;
#pragma enumsize(4)
#pragma enumsign("unsigned")
typedef struct _IntGroup
{
uint UnknownInts[15];
} IntGroup;
typedef struct _Chunk1
{
uint Type; //0: 0x1C bytes of ??
//2: 0x5C bytes of ??
//4: a float block
switch(Type)
{
case 0:
uint Unknown0[7]; //size likely inaccurate
break;
case 2:
uint Unknown2[3];
break;
case 3:
//This is the last chunk of the "chain"
break;
case 4:
uint Unknown41[3];
uint NumberOfFloatGroups;
uint Unknown42[5];
FloatGroup Floats[NumberOfFloatGroups];
break;
case 9:
//yet to understand
break;
}
} Chunk1;
struct Obj_SUZHeader
{
uint IntGroupCount;
uint PaddingDwordCount;
uint FirstChunkSize;
uint SecondChunkSize;
//FirstChunk begins here
uint Zero;
uint HeaderSizeRepeat;
uint PaddingDwordCountRepeat;
uint Zeros[4];
IntGroup BunchOfBunchOfInts[IntGroupCount];
uint Padding[PaddingDwordCount]; //full of zeros
blob FirstFile[FirstChunkSize-(PaddingDwordCount*4)-(IntGroupCount*60)-28];
//end of first chunk
blob SecondChunk[SecondChunkSize]; //may contain Several .dds
//unknown past this
}; | This is an HexWorkshop .hsl structure viewer library.
This was tested on obj_driver_gal_pmt.sz and obj_DRIVER_SPECIAL_pmt.sz.
As for the spr_*.suz it's my findings are a lot messier, probably some of the things I thought I found are just wrong:
Code: | #include "standard-types.hsl"
#pragma displayname("Outrun 2006 SUZ files") ;
#pragma byteorder(little_endian)
typedef DWORD uint ;
#pragma enumsize(4)
#pragma enumsign("unsigned")
typedef struct _FloatGroup
{
float Float1;
float Float2;
float Float3;
byte Unknown[0x10];
} FloatGroup;
typedef struct _Chunk1
{
uint Type;
switch(Type)
{
case 0:
uint Unknown0[7]; //size likely inaccurate
break;
case 2:
uint Unknown2[3];
break;
case 3:
//This is the last chunk of the "chain"
break;
case 4:
uint Unknown41[3];
uint NumberOfFloatGroups;
uint Unknown42[5];
FloatGroup Floats[NumberOfFloatGroups];
break;
case 9:
//yet to understand
break;
}
} Chunk1;
struct Spr_SUZHeader
{
uint HeaderSize; //payload starts at HeaderSize+8
uint FirstFileSize;
uint SecondFileSize;
uint SizeOfChunk1List; //everything after that
Chunk1 SomeRecord;
//several other Chunk1
uint Three; //the last Chunk1
}; | My current theory is that you add Chunk1s to Spr_SUZHeader until you find one that has its Type=3. And there are still many things I don't understand between the last Chunk1 and the first file.
|
|
Back to top |
|
|
HowardC Cheater Reputation: 0
Joined: 24 Mar 2013 Posts: 38
|
Posted: Mon Apr 01, 2013 9:04 am Post subject: |
|
|
Interesting stuff. At this point I'm not even sure if the header has a purpose (or much of one anyway). Looking into the files with the XPR0 header, these apparently define the DDS textures as well, or at least all signs point to this. So if the game can read the texture data via that file, wtf is the header for?
Perhaps that's the issue? The game engine was crudely ported from the xbox so a .xm/whatever file originally had xbox style dds textures (which strip the header off I believe) to go with the mesh and this new header re-directs those pointers to the updated DDS files?
It's been suggested that the cxbx guys could help and that might be a good suggestion. They should at least be more familiar with the XPR0 container so I could confirm if the texture calls in that file are valid or not.
|
|
Back to top |
|
|
|