.rez

Exactly how does it work?

I've searched, and I've searched, and I've searched, and I have yet to turn up a post about how the .rez format works.

If you were writing a program and needed to tell it how to save the file in the .rez format, what would you tell it, since there are no resource forks in Windows?

And I don't mean specific commands, just how the .rez file is set up.

You could save it as a text file and then import it into EVNEW manually. That's what most people do. 🙂

The file is seperated into 3 main sections...
1. File header (contains offsets to each resource as well as the resource map)
2. Resource Entries (the resources themselves as written in the Nova Bible)
3. Resource Map(Contains an entry number, resource type, resource ID
                 and name of the resource in the same order the resources
                 themselves are listed in the file)

File Header & Offset list - (INTEL BYTE ORDER)
   42 52 47 52 - Header
   LONG - 01 00 00 00 unknown
   LONG - Offset of end of header(before the "resource.map" line, actually it seems to always point to the first 'e' in the 'resource.map' string at the end)
   LONG - 01 00 00 00 unknown
   LONG - Number of first resource in Index (all index entries are numbered sequentially starting with this number)
   LONG - Number of entries in Index

   repeated for each resource entry {
       LONG - resource offset
       LONG - resource length
       LONG - Unknown ( the last entry in the list contains it's own offset, for all other entries this is 00 00 00 00)
   }
   "resource.map" - 12 byte String
   00 - null terminator 


**everything else appears to be in Motorola byte order 

Resource Entries-
      These are defined in the Nova Bible. 
      Each entry is immediately followed by the next
      Here's the format of the a few of the resource types...

// 1860 bytes
struct Ship {
   SHORT    shipHolds;
   SHORT    shipShield;
   SHORT    shipAccel;
   SHORT    shipSpeed;
   SHORT    shipTurn;
   SHORT    shipFuel;
   SHORT    shipFreeMass;
   SHORT    shipArmor;
   SHORT    shipShieldRecharge;
   SHORT       shipWeapon1;
   SHORT       shipWeapon2;
   SHORT       shipWeapon3;
   SHORT       shipWeapon4;
   SHORT       shipWeapon1Count;
   SHORT       shipWeapon2Count;
   SHORT       shipWeapon3Count;
   SHORT       shipWeapon4Count;
   SHORT       shipWeapon1Ammo;
   SHORT       shipWeapon2Ammo;
   SHORT       shipWeapon3Ammo;
   SHORT       shipWeapon4Ammo;
   SHORT     shipMaxGuns;
   SHORT     shipMaxTurrets;
   SHORT     shipTechLevel;
   LONG    shipCost;
   SHORT     shipDeathDelay;
   SHORT    shipArmorRecharge;
   SHORT    shipExplode1;
   SHORT    shipExplode2;
   SHORT     shipDispWeight;
   SHORT     shipMass;
   SHORT     shipLength;
   SHORT     shipAI;
   SHORT     shipCrew;
   SHORT     shipStrength;
   SHORT     shipGovmnt;
   USHORT     shipFlags;
   SHORT   shipPodCount;
   SHORT   shipDefaultItem1;
   SHORT   shipDefaultItem2;
   SHORT   shipDefaultItem3;
   SHORT   shipDefaultItem4;
   SHORT   shipDefaultItem1Count;
   SHORT   shipDefaultItem2Count;
   SHORT   shipDefaultItem3Count;
   SHORT   shipDefaultItem4Count;
   SHORT   shipFuelRegen;
   SHORT   shipSkillVar;
   USHORT   shipFlags2;
   ULONG  shipContributes;
   ULONG  shipContributes;
   CHAR     shipAvailability(255);
   CHAR     shipAppearOn(255);
   CHAR     shipOnBuy(256);
   SHORT   shipDeionize;
   SHORT   shipIonizeMax;
   SHORT   shipKeyCarried;
   SHORT   shipDefaultItem5;
   SHORT   shipDefaultItem6;
   SHORT   shipDefaultItem7;
   SHORT   shipDefaultItem8;
   SHORT   shipDefaultItem5Count;
   SHORT   shipDefaultItem6Count;
   SHORT   shipDefaultItem7Count;
   SHORT   shipDefaultItem8Count;
   ULONG     shipRequire;
   ULONG     shipRequire;
   SHORT   shipBuyRandom;
   SHORT   shipHireRandom;
   CHAR     Unused(68);
   CHAR     shipOnCapture(255);
   CHAR     shipOnRetire(255);
   CHAR     shipShortName(64);
   CHAR     shipCommName(32);
   CHAR     shipLongName(128);
   CHAR     shipMovieFile(32);
   SHORT   shipWeapon5;
   SHORT   shipWeapon6;
   SHORT   shipWeapon7;
   SHORT   shipWeapon8;
   SHORT   shipWeapon5Count;
   SHORT   shipWeapon6Count;
   SHORT   shipWeapon7Count;
   SHORT   shipWeapon8Count;
   SHORT   shipWeapon5Ammo;
   SHORT   shipWeapon6Ammo;
   SHORT   shipWeapon7Ammo;
   SHORT   shipWeapon8Ammo;
   CHAR     shipSubtitle(64);
   USHORT     shipFlags3;
   SHORT     shipUpgradeTo;
   LONG     shipUpgradeCost;
   LONG     shipSellValue;
   SHORT     shipEscortType;
   CHAR     Unused(16);

// 192 Bytes
struct Govt {
   SHORT   VoiceType;
   USHORT   Flags;
   USHORT   Flags2;
   LONG   ScanFine;
   SHORT   CrimeTol;
   SHORT   SmugPenalty;
   SHORT   BoardPenalty;
   SHORT   KillPenalty;
   SHORT   ShootPenalty;
   SHORT   InitialRec;
   SHORT   MaxOdds;
   SHORT   Class1;
   SHORT   Class2;
   SHORT   Class3;
   SHORT   Class4;
   SHORT   Ally1;
   SHORT   Ally2;
   SHORT   Ally3;
   SHORT   Ally4;
   SHORT   Enemy1;
   SHORT   Enemy2;
   SHORT   Enemy3;
   SHORT   Enemy4;
   SHORT   SkillMult;
   USHORT   ScanMask;
   CHAR   CommName(16);
   CHAR   TargetCode(16);
   ULONG Require;
   ULONG Require;
   SHORT InhJam1;
   SHORT InhJam2;
   SHORT InhJam3;
   SHORT InhJam4;
   CHAR   MediumName(64);
   ULONG Color;
   ULONG ShipColor;
   SHORT Interface;
   SHORT NewsPict;
   CHAR Unused(16);
};

// 1860 Bytes
struct Miss {
   SHORT  AvailStel;
   SHORT Unused;
   SHORT  AvailLoc;
   SHORT  AvailRecord;
   SHORT  AvailRating;
   SHORT  AvailRandom;
   SHORT  TravelStel;
   SHORT  ReturnStel;
   SHORT  CargoType;
   SHORT  CargoQty;
   SHORT  PickupMode;
   SHORT  DropOffMode;
   USHORT  ScanMask;
   SHORT Unused;
   LONG  PayVal;
   SHORT ShipCount;
   SHORT ShipSyst;
   SHORT ShipDude;
   SHORT ShipGoal;
   SHORT ShipBehav;
   SHORT ShipNameID;
   SHORT ShipStart;
   SHORT CompGovt;
   SHORT CompReward;
   SHORT ShipSubtitle;
   SHORT BriefText;
   SHORT QuickBrief;
   SHORT LoadCargText;
   SHORT CompText;
   SHORT FailText;
   LONG TimeLimit;
   SHORT CanAbort;
   SHORT ShipDoneText;
   SHORT Unused;
   SHORT AuxShipCount;
   SHORT AuxShipDude;
   SHORT AuxShipSyst;
   SHORT Unused;
   USHORT Flags;
   USHORT Flags2;
   SHORT Unused;
   SHORT Unused;
   SHORT RefuseText;
   SHORT AvailShipTyp;
   CHAR AvailBits(255);
   CHAR OnAccept(255);
   CHAR OnRefuse(255);
   CHAR OnSuccess(255);
   CHAR OnFailure(255);
   CHAR OnAbort(255);
   LONG Require;
   LONG Require;
   SHORT DatePostInc;
   CHAR OnShipDone(255);
   CHAR AcceptButton(32);
   CHAR RefuseButton(32);
   SHORT DispWeight;
   CHAR Unused(17);
};

Resource Map-
   **this is the last entry in the offset index.
   
   LONG - Unknown (always 00 00 00 08 from what I've seen)
   LONG - Number of resource types in the file

    repeated for each type of resource included in the file
    {
         4 Byte String - Resource type name
         LONG - Offset from beginning of resource map to first entry of that type
         LONG - Number of entries of that resource type
    }

    repeated for each resource entry {
         LONG - Index of resource in file starting from the number defined in the resource.map
         4 Byte STRING - resource type ("sp•n", "shŠn", "bššm"...)
         SHORT - Object ID (in game terms, i.e. Federation govt is ID 128)
         256 Bytes - ANSI String - Object 'Name' (any additional space is filled with buffer overrun)
    }

EOF

This post has been edited by orcaloverbri9 : 02 January 2006 - 11:23 PM

Aha! Thank you very much!

Oh, do note that the resources themselves are identical bit-for-bit to the Mac resources. If you were, say, writing a program to convert from resources to .rez, you could just get the data through resource manager routines or whatever, and then write it straight to the .rez file. In fact, the .rez format is very similar to the resource fork format (except easier, and I say this as someone who has written the routine to create a resource fork from scratch using resource manager routines :)).

Also, be sure to keep in mind that for whatever unfathomable, mindboggling reason, the endian order switches halfway through the file. Specifically, the header is little endian, and the rest is big endian. Every explicit value stated in the above description is big endian, so 42 52 47 52 is actually 52 47 52 42, but when interpreted by a Mac is 42 52 47 52.

Just a few random things I figured I'd mention.

This post has been edited by orcaloverbri9 : 03 January 2006 - 03:03 AM

Not exactly. You shouldn't try interpreting 42 52 47 52 as a long integer, because it is a sequence of ASCII bytes meaning BRGR, Burger, and as such it is endian neutral just like "resource.map".

However, when writing a four-char constant such as 'BRGR' in C on a Mac, it means the integer 0x42524752 (this is in fact a convention from gcc, the only Mac compiler to support the two different endian orders: indeed the C standard requires the representation of multiple-character constants to be implementation-defined, which means a compiler has to make a choice, document it, and stick with it on the matter) whose memory representation (and hence file representation) depends on the current byte order. On a big-endian machine, this is the sequence of bytes 42 52 47 52; on a little endian machine, 52 47 52 42, which doesn't match the header. So to be sure you have a constant that matches, you'd use something like:

#ifdef LITTLE_ENDIAN
#define BURGER_MAGIC 'RGRB'
#else
#define BURGER_MAGIC 'BRGR'
#endif
(of course, I'd better use OSSwap*Const stuff, but I don't really know them)

To sum up, 'abcd' ­­­!= ((UInt32)"abcd"). See the Universal Binary Programming Guidelines for Apple's info.

Another reference is the source for the bin-to-rez converter, but Burger's site seems to be down at the moment, so you can't check it right now.

Hey guys,

I was thinking the same thing, there does appear to be a lack of Dev tools for the PC, I've got some experience developing Win apps so would be keen to look at this.

orcaloverbri9 - thanks for the info on the file structure, v. useful.

I do have a couple of other questions though...

1. Actually getting to the data in the .rez file, I have opened it usng Text pad in ASCII and Binary mode and can't make head nor tail of the .rez file, am I beig stupid?

2. Using the provided file structure within your application, what is the best way to intergrate it?

3. Dev envionment, any recommended Languages/Tools?

4. Further info, are there any other sites/posts with more information in them, this appear to be the only one I have seen?

Thanks for any answers in adavnce.

Cheers
Stedders

1. You won't be able to get anything out of it like that. If you really wish to read it, I recommend a hex editor. Use the format I posted above to help decipher the seeming nonsense.

2. I don't quite understand this question. Could you be more specific?

3. Not being a Windows developer, this isn't my area. However, it's apparently doable with C++ and I'd imagine C could do it. I'd recommend asking Aprosenf about it.

4. Go to the top of the page and click on "Search", then click on "More Options...". Enter "rez format" for the search and "Mehrunes" for the author, then click "Perform Search". You'll see a topic about the .rez format by seant. I suggest you read it. 🙂

This post has been edited by orcaloverbri9 : 09 January 2006 - 05:37 PM

Thanks orcaloverbri9.

orcaloverbri9, on Jan 8 2006, 04:03 PM, said:

1. You won't be able to get anything out of it like that. If you really wish to read it, I recommend a hex editor. Use the format I posted above to help decipher the seeming nonsense.

2. I don't quite understand this question. Could you be more specific?

Makes a lot more sense, viewed in a Hex editor and Textpads binary mode and can now see what you mean, you answered the second point with the first answer.

orcaloverbri9, on Jan 8 2006, 04:03 PM, said:

3. Not being a Windows developer, this isn't my area. However, it's apparently doable with C++ and I'd imagine C could do it. I'd recommend asking Aprosenf about it.

Yeah, I've seen the source for EVNEW, am going to be ploughing through it to see how it has been designed, I could write it in C++ but would prefer to use Java as I need to learn it for Uni and this would be a "fun" project to do.

orcaloverbri9, on Jan 8 2006, 04:03 PM, said:

4. Go to the top of the page and click on "Search", then click on "More Options...". Enter "rez format" for the search and "Mehrunes" for the author, then click "Perform Search". You'll see a topic about the .rez format by seant. I suggest you read it. 🙂
View Post

OK, feel like a bit of a Newb now, cheers 😉

stedders, on Jan 8 2006, 03:12 PM, said:

Yeah, I've seen the source for EVNEW, am going to be ploughing through it to see how it has been designed, I could write it in C++ but would prefer to use Java as I need to learn it for Uni and this would be a "fun" project to do.

Well, they're close, so writing it in Java from C++ shouldn't be too difficult as far as porting large applications between languages goes.

Java and C++ are worlds apart. I've learned both, and let me tell you, a port would not be a trivial exercise.

Dave @ ATMOS

Aside from the fact that Java is an interpreted language unsuitable for writing large applications...

Is there a Java compiler?

pipeline,

Quote

Java and C++ are worlds apart. I've learned both, and let me tell you, a port would not be a trivial exercise.

You're spot on there, C++ and Java do have a lot of thing in common but they do also differ a lot as well, in this case it will primarily be Memory Management and Windows interface implementation, I also have experience in both.

Quote

Well, they're close, so writing it in Java from C++ shouldn't be too difficult as far as porting large applications between languages goes.

I am not looking to port EVNEW, I want to build a utilities set that would specialise in certain things, system creation/mapping, port/weapon/ship creation, and then pull it together within a single app, I'm more looking at the challenge of building it from scratch, rather than ripping off what someone has alredy done.

Quote

Aside from the fact that Java is an interpreted language unsuitable for writing large applications...

Is there a Java compiler?

I don't like flaming people, so I won't....do you have any experience with Java, or other such interpreted languages?

A large application can be written in Java and, depending on the situation, may be best written in such a language, if you want cross-compatibility, more control over execution/security and running speed isn't an issue, this is the case for 75%+ applications.

Where running speed is an issue, in such processor intense apps such as Games, 3D modelling and scientific apps, C/C++ is the best choice as you have direct access to the memory on the machine and can use nasty things, such as pointers, to manipulate the data in memory in the most efficient manner.

Also C/C++ and Basic can also be considered a interpreted language, there are applications out there that allow you to run such apps from the source via an interpreter, Java on the other hand is in fact a half-interpreted language, the Java source is compiled into bytecode, which is platform independant, it is this code that is run by the Java interpreter, improving performance over most interpreted languages, eg. Perl/Python.

Yes there is a Java Compiler, a Java app can't be run without it being compiled first.

The reason I mentioned Java is that it is the weakest of my core languages, out of C#, Perl, Python, VBasic, Basic, PHP and JavaScript, I would be able to build a Mac and PC version at the same time and as I do a lot of my developing on Linux I can't really build a C/C++ app and then port it to Windows/Mac as easily.

Thanks for everyone’s comments and help, if anyone else has some good pointers, or feel I have misrepresented something in the above text, feel free to comment.

stedders, on Jan 9 2006, 11:11 PM, said:

Where running speed is an issue, in such processor intense apps such as Games, 3D modelling and scientific apps, C/C++ is the best choice as you have direct access to the memory on the machine and can use nasty things, such as pointers, to manipulate the data in memory in the most efficient manner.

Most programmers would not consider pointers to be evil. 🙂 Java's weakness is that it's a slow language, compiled, and a mass of treacle when interpreted.

It has many excellent features, but being useful where speed of calculation is required is not one of them.

Dave

pipeline, on Jan 9 2006, 02:39 AM, said:

Java and C++ are worlds apart. I've learned both, and let me tell you, a port would not be a trivial exercise.

Dave @ ATMOS

Ah. Well, that was a guess on my part. I've heard that C++ and Java are similar, so I just assumed, having no experience with C++ and minimal failed experience with Java.

That said, it's still easier than many cross-language ports would be; Java is at least still OO. I've never personally tried going from OO to procedural, but in a large-scale, non-simple application, I'd imagine it's not fun.

Of course, I could be wrong.

This, however, I am sure of: Java compilers exist, but Java applications are slower than sin and kludgier than a grandma with a broken leg. On Mac at least.

Of course, it would allow it to be cross-platform, but there are better solutions for that than Java.

This post has been edited by orcaloverbri9 : 09 January 2006 - 05:40 PM

pipeline, on Jan 9 2006, 09:24 PM, said:

Most programmers would not consider pointers to be evil. 🙂 Java's weakness is that it's a slow language, compiled, and a mass of treacle when interpreted.

It has many excellent features, but being useful where speed of calculation is required is not one of them.

Dave
View Post

Pointers are evil, they are, they are, they are.....had some bad experiences with them, was trying to be too clever, didn't work and caused some serious memory leaks in a previously stable app :blink:

orcaloverbri9, on Jan 9 2006, 10:37 PM, said:

Of course, it would allow it to be cross-platform, but there are better solutions for that than Java.
View Post

<_< - such as?

stedders, on Jan 10 2006, 06:53 AM, said:

<_< - such as?

I said better, not easier or cheaper, if you catch my drift. 😉

stedders, on Jan 10 2006, 10:53 PM, said:

Pointers are evil, they are, they are, they are.....had some bad experiences with them, was trying to be too clever, didn't work and caused some serious memory leaks in a previously stable app :blink:
View Post

Correct use of pointers seperates the good programmers from the average. That's we were taught in "Algorithms & Metrics" at University. 🙂