Jump to content
COMBATSIM Forum
Krycztij

TAW terrain format

Recommended Posts

Thanks for the update. :) Will try it out later..

The jumps are tricky, and we don't know all the rules yet....but your work is a big help with this.

This is not correct though:

0007 jump if damage flag is set

As far as I can see, 0007 is just another flag. For instance, if it is set, then the building shadows are drawn. It can be used in other places as well though.

The damage is set by 'Parameter' 0007.

In broad terms, these parameters can be considered as class 'attributes, and are set from elsewhere.

I would go about this way:

1. On loading a model, create 25 variables for the 'parameters' and initialize them to zero

2. start with parameter 0 as the current active parameter.

then, when running the bytecode

3. when you come across 0020,0021,0022 compare the operand with the value of the current active parameter.

4. For 0048, change the current active parameter to the value of the operand

There is a usability problem in that it would be nice to know which parameters are used in a particular model so that only the used parameters are available for adjustment with the buttons. This would require a scan through the file before the bytecode is run though. I could help with a lookup table for now if it's any help.

Known parameters

0000 General purpose

0007 Damage

000a F22 camo

From the EF2000 file, we see that some parameter controls the chute, and another the afterburner...but we don't know which.

Share this post


Link to post
Share on other sites
This is not correct though:

0007 jump if damage flag is set

As far as I can see, 0007 is just another flag. For instance, if it is set, then the building shadows are drawn. It can be used in other places as well though.

Oh yes, it makes much more sense that way. I'll correct it immediately.

I would go about this way:

1. On loading a model, create 25 variables for the 'parameters' and initialize them to zero

2. start with parameter 0 as the current active parameter.

then, when running the bytecode

3. when you come across 0020,0021,0022 compare the operand with the value of the current active parameter.

4. For 0048, change the current active parameter to the value of the operand

Okay, I'll start implementing it like that right now!

There is a usability problem in that it would be nice to know which parameters are used in a particular model so that only the used parameters are available for adjustment with the buttons. This would require a scan through the file before the bytecode is run though. I could help with a lookup table for now if it's any help.
That would be great! Could you provide one four-byte number per model with the n'th bit set if the n'th parameter is used -- e.g. 00000082 hexadecimal (which is 1000 0010 binary) as an indicator that parameters #7 and #1 (zero-based) are used? If that's too much to ask for, I could also work with a list of 25x 0 and 1, or 'false' and 'true'.

Share this post


Link to post
Share on other sites

Up and running! Here is a first report on the parameters and the Eurofighter model:

0 landing gear in/out

1 parachute in/out

2 no effect observed

3 lights off, engines off / lights on, engines dimming / engines firing / afterburner

4 air refuel receiver in/out

5 cycle nationality marking

6 open canopy / closed canopy with empty cockpit / closed canopy

7 nothing drawn if above 8

8-24 no effect observed

I need to clean up, modify the keyboard input and the text output and I hope to send you an update this evening.

Share this post


Link to post
Share on other sites

Excellent, well done!

I'll get that list to you when I can, but unfortunately I have a pile of non-TAW related stuff to do first. :(

When scanning for which parameters are used, I'll also try to calculate their max and min values so that limits can be set on the values that can be chosen with the buttons.

I guess that this should be done per LOD, but I think I'll just have one list per .3 file for now.

Share this post


Link to post
Share on other sites
When scanning for which parameters are used, I'll also try to calculate their max and min values so that limits can be set on the values that can be chosen with the buttons.

I guess that this should be done per LOD, but I think I'll just have one list per .3 file for now.

No rush :) My impression is that the parameter set for most models will be rather slim anyway, so a simple set of used/unused flags will suffice for first explorations.

Share this post


Link to post
Share on other sites

Outstanding progress as usual!

I've sent you a file which should help determine which parameters are used for a particular model. Hope it works.

Share this post


Link to post
Share on other sites

Here's the files where 0900 occurs, and an example line.....I have no idea what it does differently.

hut1n_90.3

hut2n_90.3

hut2n_90.3

hut_1n.3

hut_2n.3

prfb90.3

prfb_180.3

prfb_90.3

s_prefab.3


0058; 009f001800180900ffff004000b5005000b5005000bd004000bd009e000e001100120015

Here are some in-game screenshots of 009f0018xxxx0900...using hut_1n.3:

Option Setting: Build_Texture=1

hut-n1-orig-tex1.jpg

Option Setting: Build_Texture=0

hut-n1-orig.jpg

Option Setting: Build_Texture=0

All 009f0018xxxx0900 modified to 009f0018xxxx0901

hut-n1-0901.jpg

Considering the other 3 types: 0103, 0301 and 0401, I would be inclined to consider that the 3rd word after the 009f opcode could be split into two instructions. The first byte instruction which is to fetch the following number of palette colors and the second determines the number of vertex indices in 009D/009E to which each color is assigned. Does that seem reasonable?

There are other variations found in the reserve files:

eg: 009F0018004F0900000900010001002000010020002000010020008E00040027002C002D

Share this post


Link to post
Share on other sites

I just recalled, the player F-22 should be interesting to see, the reason being that the damage model seems to be more complex in that regard that one some sets you can have a torn wing, but it isn't consistent with damage.

Share this post


Link to post
Share on other sites

I've sent you a file which should help determine which parameters are used for a particular model. Hope it works.

Yes, I'm still implementing it. Thank you.

Here are some in-game screenshots of 009f0018xxxx0900...using hut_1n.3:

Thank you, too. It's the next thing on my to do list right after Mike's parameters.

I just recalled, the player F-22 should be interesting to see, the reason being that the damage model seems to be more complex in that regard that one some sets you can have a torn wing, but it isn't consistent with damage.

The player F-22 is by far the most complex model there is and it even has some special features which do not occur in other files (e.g. backward jumps). Currently, we are still having major problems with it and my prediction is that it will be the very last model we will be able to render properly :(

playerf22.png

Share this post


Link to post
Share on other sites

Backward jumps are far more widespread than just the F22 files. As my parser was evolving, I had to assume that any jump could be backwards for any jump opcode.

This shouldn't be a big deal if you treat the jump operand as a 16-bit signed integer.

The next thing I'm going to do when I get time is to try and address the jump questions posted on the previous page.

Share this post


Link to post
Share on other sites

The unused parameter flags work fine. They are now showing "(idle)" behind a parameter's index. I think this is better than skipping them, because if you start to mod files you don't want the parameters to be unreachable although you implemented them, just because the viewer cannot see it's not the original file any more.

Here is the hut:

hut.png

The 0900 format is strange: FFFF 0000 color0 0000 color1 0000 color2 0000 color3

I have no idea how the engine rendered this:

Option Setting: Build_Texture=0

hut-n1-orig.jpg

This is actually the texture which is hard-coded in the file (TRG_16), but there are no texture coordinates and Build_Texture is off ...

... also note that the front part of the hut is too far off in my rendering. I have no idea what's going on.

Share this post


Link to post
Share on other sites

009f001800180900ffff 0040 00b5 0050 00b5 0050 00bd 0040 00bd 009e000e001100120015

                     u1   v1   u2   v2   u3   v3   u4   v4

Aren't these texture coordinates?

Share this post


Link to post
Share on other sites


009f001800180900ffff 0040 00b5 0050 00b5 0050 00bd 0040 00bd 009e000e001100120015

                     u1   v1   u2   v2   u3   v3   u4   v4

Aren't these texture coordinates?

Yes. Apparently we are using the redxxxx.ini [surface] section texture '24'

24=txtr 4,(128,64),(159,64),(159,95),(128,95) ;S MUD+WOTTLE

...only it is now using the 009f UV coordinates instead? That might explain the presence of the 008e in the other variants.

Now I see Krycztij's statement above, TRG_16.tm and not Material.tm

Share this post


Link to post
Share on other sites

Mike, you are right -- these are indeed texture coordinates. I don't know why the u component was always zero in my prototype here. It's nonzero now. I must had made a mistake somewhere.

But there is still a problem: 009E is usually the instruction to draw a Gouraud-shaded quad if Build_Texture is zero, and to draw a textured quad (with coordinates from red****.ini) otherwise. Now, however, it draws a textured triangle even if Build_Texture is zero, but seemingly only if it was preceeded by 009F-0900. I have no idea how the engine figured this out, other than setting a special flag if the last instruction was 009F with 0900 subtype (and clearing this flag after the next draw call).

Also, I disagree on splitting 009F: I have not yet seen any opcode in the range above 00AF, but 0301, 0401 and 0900 would then be new opcodes.

This seems completely inconsistent and too complicated to me; I have no clue what's the purpose of all that. On the other hand, I can understand the 009F-0900-008E version DrKevDog mentioned: 009F-0900 fetches four texture coordinates and 008E is the opcode to draw a textured polygon. But then again, I don't know why there is not just a 002E or 0047-type instruction ("fetch n texture coordinates") instead of the seemingly identical, but heavier 009F.

Share this post


Link to post
Share on other sites

This engine was quite old by the time TAW came along, and we may be seeing a mixture of different ways to do the same thing.

I have been updating the opcode list, at least as I see it. There appear to still be some gaps in our knowledge. :)

My plan is to investigate the ???s by modifying my parser to look for patterns etc.

Feel free to correct my assumptions...

Vertex related, fairly well understood  

0061;707.3  

0062;707.3  

0063;707.3  

0064;707.3  

0065;707.3  

0066;707.3  

0067;707.3  

0068;707.3  

0069;707.3  

006a;707.3  

006b;707.3  

006c;707.3  

006d;707.3  

006e;abu.3  

006f;707.3  

0070;707.3  

0075;707.3  


Vertex related, not understood  

004a;aihq_180.3   ???

0051;a101.3       ???

0052;aswan_j.3    Separate scale in XYZ ???

0053;aswan_j.3    Probably understood now. Set of explicitly defined vertices, but why. Speed ???

0077;aswan_j.3    ???


Scale  

0030;707.3  


Terminators  

0000;707.3   

0084;aihq_180.3  (terminates 0083)

00a8;atgtrail.3  (terminates 00a7)

ffff;707.3 


Polygons,points,lines etc. Don't necessarily know what they do.... 

0001;707.3       OK

0002;707.3       OK

0003;707.3       OK

0004;ian_0.3     OK

001a;aswan_j.3   Defines a triangle ???

001b;aihq_180.3  Defines a quad ??? 

002e;707.3       OK

002f;a101.3      OK, what is difference to 008e, filtering ???

0031;ses.3       ???

0033;707.3       Light, but what is the difference to 0034

0034;707.3         "      "    "   "       "    "     0033

0038;707.3       ???

0039;aden_b.3    Streetlights.

003e;dust.3      ???

0047;707.3       OK

004c;707.3       OK

004d;chaparal.3  OK

004e;707.3       OK

004f;707.3       Seems to draw quad, but what difference to 0081 ???

005c;anglo.3     sphere ???

005d;contrail.3  sphere ???

005f;ian_0.3     ???

0060;car.3  	 Used for parachutes ???

0071;707.3       OK

0072;707.3       OK

0073;ian_0.3     OK, linked to 0004

007d;a50.3       Same format as 0003, but what is the difference ???

007e;apache1.3   Flat shaded quad ???

0080;707.3       OK

0081;707.3       OK

0083;aihq_180.3  No idea, terminated by 0084 ???

0088;707.3       OK

008d;awc_ef20.3  OK 

008e;707.3       OK

0094;awc_f14.3   May need to move to unknown jumps section ???

0095;707.3       Light, maybe off, associated with 0033 ???

0096;707.3       Light, maybe off, associated with 0034 ???

0098;abdostem.3  OK probably, adjusts transparency level

009d;rymq_180.3  OK

009e;skyn90.3    OK

009f;abdostem.3  OK, should really split this into two parts since 009d and 009e can be freestanding.

00a2;f22clegy.3  Maybe shadow related ???

00a7;atgtrail.3  Sets AGP 24 bit colour


Decisions and jumps, sort of understood  

0007;a101.3      Jump if 0007 flag set

0008;707.3       Jump to subroutine

0015;707.3       Visibility test  

0043;abdostem.3  Related to time of day, bitmask test

0020;abdostem.3  Parameter <

0021;707.3       Parameter =

0022;707.3       Parameter >

0027;707.3       Distance >

0048;707.3       Parameter Select

00a3;atgtrail.3  Test for AGP


Decisions and jumps, not understood.  

0024;707.3        >= ???

0025;707.3        <= ???

0026;avengr.3     Distance= ???

002d;707.3        Perform some action on vertex then jump, Setup for billboarding ???

003f;707.3        Lights on/off, Test for values, 128,64,4 (j707 contains both 128 & 64)

0040;a101.3       Same form as 003f, Test for value 128 only

0041;barracks.3   Same form as 003f, Test for value 128 only

0042;air_hq.3     Same form as 003f, Test for values 0,4,128

0045;fact90.3     Same form as 003f, Test for value 128 only

0049;707.3        Rotation, will worry about this later

004b;a101.3       Same form as 003f, Test for values 2,3

0076;abtw_1ra.3   (assume true) 

007b;abtw_1ra.3   (assume true)

007c;f22egypt.3   (assume true)

0086;f22egypt.3   Similar to 002d, related to parameter 0003 in F22 ???

0087;a101.3       (assume true)

0093;abtw_1ra.3   (assume true)


Haven't got a clue  

0037;a50.3        Some action like 0030 ??? Should be safe to ignore to see what happens.

0054;newhoriz.3   Found at start of certain files. Ignore unless it expects a terminator.

Share this post


Link to post
Share on other sites

Thank you for the list. I'll immediately compare it to mine.

I forgot, there is something I'm very unsure of from the beginning -- it's the lifetime of the UV coordinates.

While vertices are stored in an array with random access, it seems like UV coordinates (and vertex colors) are stored on a stack. A 002E/0047 ("fetch n UV coordinates") or 009F instructions pushes n UV onto that stack, and upon the next draw instruction, the last UV coordinates are used and then popped from the stack.

I have NOT implemented these stack semantics yet. I am storing all texture coordinates of the entire model in a continuous array. The reasoning is: If I accidentially skip only one UV fetching instruction (e.g. because we haven't identified it yet and we don't know it's a UV push), then the next draw call will not find a sufficient number of UV coordinates, which means the program is in an inconsistent state and must be finished ergo -- which might break a lot of files depending on how many UV instructions are still unknown to us.

IF these stack semantics were actually used, and NOT the array semantics I currently use, then one could simply check whether the triangle has to be drawn with texture or Gouraud-shaded: If there is a nonzero number of UV on the stack, the texture is used. Otherwise, Gouraud-shading is used.

009F would then push UV coordinates onto the stack if Build_Textures is 1, and colors otherwise. 009F-0900 would always push UV coordinates, but it would push the hard-coded ones and read them from red****.ini if Build_Textures is 0. If every vertex color / UV coordinate fetch would always be followed by a draw call of the same number of vertices, things would even become easier.

I doubt we'll have any chance to find out what's going on if I don't just implement stack semantics and test all models. If some break, I'm wrong with the stack and it's an array. This will take a lot of time and it might end frustrating.

Share this post


Link to post
Share on other sites

Feel free to correct my assumptions...


0033;707.3       Light, but what is the difference to 0034

0034;707.3         "      "    "   "       "    "     0033


0039;aden_b.3    ???

My impression is that 0033 is used for signal lights (at airports and planes) which have no individual attenuation (if you open airport and plane lights in the model viewer, you will see that the color change over distance is hard-coded for all lights in the file) while 0034 lights are used for city lights etc and become reddish with distance (but I haven't checked this).

0039 draws n pairs of street lights of a given color between two given position indices.

I didn't know about 004D, 004F, 0073, 007E and 008D. Can you tell me more about that (if it's not in the scripts already)? I'll immediately start implementing 007D.

Share this post


Link to post
Share on other sites

How could I forget about 0039 streetlights? :huh: I've updated the list.

From memory, 008D is the same as 008E but for triangles instead of quads.

0073 produces a >4 sided polygon, with palette colour set by a previous 0004 line like the 0002/0071 and 0003/0072 combinations.

004d,004f & 007e I can't remember right now, but will explain tomorrow if required.

I'm too tired to think about your earlier deep question, but I've always thought about it as a state machine model so, for instance, the texture coordinates u1,v1,u2,v2,u3,v3,u4,v4 are variables that are set, used (create renderer specific commmand) and overwritten by the next fetch instruction. Thus the lifetime is very short indeed.

Share this post


Link to post
Share on other sites

Also, I disagree on splitting 009F: I have not yet seen any opcode in the range above 00AF, but 0301, 0401 and 0900 would then be new opcodes.

This seems completely inconsistent and too complicated to me; I have no clue what's the purpose of all that. On the other hand, I can understand the 009F-0900-008E version DrKevDog mentioned: 009F-0900 fetches four texture coordinates and 008E is the opcode to draw a textured polygon. But then again, I don't know why there is not just a 002E or 0047-type instruction ("fetch n texture coordinates") instead of the seemingly identical, but heavier 009F.

I agree, it makes more sense to continue 009f as Mikew described it and without any further fractionating. I do not yet understand the redundancy, however, I am sure that understanding will also come in time.

Share this post


Link to post
Share on other sites

Removed these lines from the list of opcodes, since they don't exist in TAW. So, we're back to 99 opcodes. I'm fairly sure they exist in my parser due to experiments with the earlier games, TFX and EF2000.

New, need to scan for examples 

0036 

0050 

0006 

002c

001f

...and a bit more analysis of the decision opcodes which are similar in form to 003f.

These consist of 3 words, the opcode, some operand then a jump.

For some of these, there is only one value of the operand, so can be treated as a toggle.

These are:

0040

0041

0045

which all have a operand of 128 (0x0080)

These have more than one possible value of the operand:

003f Operand can be 4, 64 , 128

0042 Operand can be 0 , 4 , 128

004b Operand can be 2 , 3

Then there are these opcodes, which even though we don't know what they do, we might as well assume the jump is always valid or we won't see anything. Thus there is no need to display an option to toggle them at this time:

0076

007b

007c

0087

0093

Now, onto the unknown polygons.

001a and 001b seem to define a triangle and quad respectively.

Suggest that they are temporarily rendered as brightly coloured polygons to see where they turn up.

Share this post


Link to post
Share on other sites

I agree, it makes more sense to continue 009f as Mikew described it and without any further fractionating. I do not yet understand the redundancy, however, I am sure that understanding will also come in time.

Okay! I'll postpone it because we have so much more to do where we can actually see progress ;)

Removed these lines from the list of opcodes, since they don't exist in TAW. So, we're back to 99 opcodes. I'm fairly sure they exist in my parser due to experiments with the earlier games, TFX and EF2000.

New, need to scan for examples 

0036 

0050 

0006 

002c

001f

Thank you! I'm always looking for ways to reduce complexity and this saves a few more lines of code.

Then there are these opcodes, which even though we don't know what they do, we might as well assume the jump is always valid or we won't see anything. Thus there is no need to display an option to toggle them at this time:

0076

007b

007c

0087

0093

Okay!

Now, onto the unknown polygons.

001a and 001b seem to define a triangle and quad respectively.

Suggest that they are temporarily rendered as brightly coloured polygons to see where they turn up.

Will implement them that way.

An update on 0049: It means something like "execute the subroutine at X to draw a mesh at position #n with rotation X Y Z". It pushes a transformation onto the stack (rotation first, then translation to the position whose index is given) and all draw calls in the subroutine use this transformation. It is popped upon the next 0000 instruction. This is the limo drawn with these semantics:

ljimo.png

It does not work compeletely yet; two of the four tires are clipped and it's always the two facing towards you. But at least the rotation and the position on half of them works as desired.

Share this post


Link to post
Share on other sites

Great work on 0049! I was dreading this....

Have you got the clipping logic the wrong way round? It would make sense that the wheels on the other side would be clipped. In game, you would never see all four wheels at the same time.

Share this post


Link to post
Share on other sites

Have you got the clipping logic the wrong way round? It would make sense that the wheels on the other side would be clipped. In game, you would never see all four wheels at the same time.

No, but I have not fully implemented the transformation stack. I do think it is a stack and not just one transformation being set: From what I see, helicopter rotors are drawn by

  • pushing the transformation of the rotor relative to the model's center
  • pushing the transformation of the first rotor blade relative to the center of the rotor
  • drawing the first blade
  • popping its transformation
  • pushing the transformation of the second rotor blade relative to the center of the rotor
  • ...
  • popping the transformation of the rotor relative to the model's center
  • drawing the rest of the model

I had just hard-coded a single transformation and I'm implementing the complete stacking now. It is quite a change in program structure; you have to take into account scaling etc.

I think the clipping problem is cyclic: TAW uses visibility tests on triangles to determine what is clipped. But some of these triangles can be transformed, too. So we need correct transformation to see what is clipped correctly, but we need correct clipping to see if the transformation is correct ...

Edit: not ... yet ... satisfying ...

chinook1.png

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...