Jump to content
COMBATSIM Forum

007F-Canopy


DrKevDog
 Share

Recommended Posts

Thanks. Replacing WINDOWS with _WIN32 makes it work fine. The header is dated 2007, so maybe the rules have changed since then.

I'm not sure yet what to do with this, but the first task will be to re-examine .3 file theory. Do we know enough to break the file into chunks which can be manipulated separately, then reassembled?

DKD, sorry for the thread hijack, but your cockpit problem (and the donkey.3 request) have re-ignited my interest in this area. :D

Link to comment
Share on other sites

The header is dated 2007, so maybe the rules have changed since then.

It's been like this since the mid-90ies, but you see non-conforming code everywhere (especially with cross-platform tools and makefiles). WINDOWS / WIN32 / _WIN32 / WIN64 / WINVER are an incredibly complex / bad solution to the very simple question Am I compiling for Windows?, so I understand developers just picking the first macro they see or adding their own when they don't understand it.

I'm not sure yet what to do with this, but the first task will be to re-examine .3 file theory. Do we know enough to break the file into chunks which can be manipulated separately, then reassembled?

We can break them down to individual LODs. If you want to break them down further (individual functions), then I recommend a data structure which groups instructions until a return statement is reached, and replaces every jump/call instruction offset with a symbolic (absolute!) value. If a group of instructions is not reachable from the start of the program, but with a jump, then it's a branch. If it's only reachable via call, it's a function. Now you can build a flow graph from the absolute offsets, much like IDA.

It's starting to sound like writing your own decompiler … maybe some papers on decompilers and program flow analysis are helpful. I never did something like that, but that's where I'd begin.

Link to comment
Share on other sites

Well, the flame can be extinguished just as easily if not enough progress gets made. :D

As Krycztij points out, a systematic approach needs to be taken. I have some code from 2010 which breaks down the simpler files, which I'll start with. Then the goal was rendering, but now 3View handles that. From the excellent 3View code comments, we now know what are jumps,branches and subroutines..

Link to comment
Share on other sites

From the excellent 3View code comments, we now know what are jumps,branches and subroutines.

Speaking of which … a lot of stuff happened since the last source code release, so I'll better post the current comments here:

FFFF
Abort execution.

0000
Return to caller by popping the current routine from the call stack.

0001 <color> <position0> <position1>
Draw a flat-shaded line of the color at palette index <color> between the <position0>-th and <position1>-th (transformed) position.

005A <color> <position0> <position1> <position2>
Not used in TFX3. Used in EF2000’s 'disc' and 'disk2'.
0002 <color> <position0> <position1> <position2>
Draw a flat-shaded triangle with the color at palette index <color>. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1> and <position2>.

0003 <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded quad with the color at palette index <color>. The indices of its vertices’ (transformed) positions are given in clockwise order.

0004 <color> <vertices> <position>[<vertices>]
Draw a flat-shaded <vertices>-sided polygon with the color at palette index <color>. It consists of at least three vertices; its (transformed) position’s indices are given in clockwise order.

0007 <offset>
Jump to the instruction at <offset> - 2 B relative to this instruction’s end.

0008 <offset>
Call the routine at <offset> - 2 B relative to this instruction’s end.

0015 <position0> <position1> <position2> <offset>
If the triangle of the (transformed) vertices at the given positions (clockwise) faces the viewer, jump <offset> - 2 bytes relative to the end of the instruction.
TFX must obtain a back-to-front draw order because there is no Z buffering; that’s what these jumps are for.

001A <opacity> <color> <position0> <position1> <position2>
Draw a flat-shaded, transparent triangle with the color at palette index <color>. If <opacity> equals 0000, the trianle is semi-transparent. If <opacity> equals 000E, it is fully transparent. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1> and <position2>.
Used to cover textured terrain with dust. Other values than 0000 and 000E could not yet be tested because we have no untouched Glide / Direct3D mode available and the software mode doesn’t support transparency.

001B <opacity> <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded, transparent quad with the color at palette index <color>. If <opacity> equals 0000, the quad is semi-transparent. If <opacity> equals 000E, it is fully transparent. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1>, <position2> and <position3>.
001B is used to cover textured terrain with dust; 003E is used in 'dust' only. Other values than 0000 and 000E could not yet be tested because we have no untouched glide / Direct3D mode available and the software mode doesn’t support transparency.

001F <unknown> 0000 0000 0000 0000 <unknown> 0000 <unknown> 0000
Used in EF2000’s 'explode' and 'explode2'.
0077 0000 0000 0000 0000 0000 0000 0000 0000 0000
The upper three rows of the current transformation’s world and view matrix are set to identity, which causes subsequent geometry of the current routine to always face the viewer. The 4th row’s X and Y coordinate is displaced by random numbers, which causes any subsequent geometry to shake.
Used in the same way as 004B ("draw staring submesh"), but for special effects like animated splashs in breaking dams and for dust trails.

0020 <reference> <offset>
If the currently active parameter is below <reference>, jump <offset> - 2 bytes.

0021 <reference> <offset>
If the currently active parameter equals <reference>, jump <offset> - 2 bytes.

0022 <reference> <offset>
If the currently active parameter is above <reference>, jump <offset> - 2 bytes.

0023 <reference> <offset>
If the currently active parameter is below <reference>, draw the submesh at <offset> - 2 bytes.

0024 <reference> <offset>
If the currently active parameter equals <reference>, draw the submesh at <offset> - 2 bytes.

0025 <reference> <offset>
If the currently active parameter is above or equals <reference>, draw the submesh at <offset> - 2 bytes.

0026 <threshold> <offset>
If the object’s distance from the viewer is below <threshold>, jump <offset> - 2 bytes.
Used to cull shapes with distance.

0027 <threshold> <offset>
If the object’s distance from the viewer is above or equals <threshold>, jump <offset> - 2 bytes.
Used to fade details, e.g. shadows, with distance.

002D <translation> <offset>
A translation to the <translation>-th raw position is pushed onto the stack and the routine at <offset> - 2 B is called. The transformation is popped when the routine returns.
Used to draw instances of the same sub-mesh at multiple locations, e.g. jet engines of airliners.

002E <texture> <number> for each <number>[<u> <v>]
0047 <texture> <number> for each <number>[<u> <v>]
Write <number> texture coordinates of a polygon. If <texture> is nonzero, the texture’s name must be looked up in the 3D file’s [globaltextures] section. Otherwise, the texture of the hard-coded name is used.
Most texture positions are in the range of [0, 255] in the U direction and [0, 191] in the V direction. There are, however, exceptions (especially when duplicating texture portions). The largest UV coordinates of TAW are found in the air HQ and in the high F-22 LODs ([0, 320] in the U and [0, 258] in the V direction); but EF2000’s coordinates are even larger.

002F <vertices> for each <vertices>[<index>]
008E <vertices> for each <vertices>[<index>]
Draw a textured <vertices>-sided polygon with the last set of texture coordinates. It consists of at least three vertices; its (transformed) position indices are given in clockwise order. The texture’s bytes are interpreted as indices to the current color palette.

0088 <vertices> for each <vertices>[<index>]
Draw a textured <vertices>-sided polygon with the last set of texture coordinates. It consists of at least three vertices; its (transformed) position indices are given in clockwise order. The texture’s bytes are interpreted as transculency information:
   — transparent (0) to opaque (31) black (used for oil spills)
   — transparent (32) to opaque (63) white (used for missile trails)
 and the current texture color from 0098, 00A7 and 00A8 instructions is used as a multiplier.

0030 <unit length>
Scale the following transformed positions by 1 ÷ <unit length>.

0031 <number> (<color>)[<number>]
Pushes the given number of vertex colors for a polygon.
TAW uses this instruction in 'ses' only; tests have shown that it just ignores it.
EF2000 uses this instruction in nine files: 'bcontwr1', 'boom', 'carr2', 'fx_bang', 'fx_boom', 'ian_bang', 'ian_boom', 'ian_fash' and 'ianboom'.

0032 <vertices> (<index>)[<vertices>]
Draw a Gouraud-shaded <vertices>-sided polygon with the colors in the color palette index buffer. It consists of at
 least three vertices; its (transformed) position’s indices are given in clockwise order.
TFX3 does not use this instruction.
EF2000 uses this instruction in nine files: 'bcontwr1', 'boom', 'carr2', 'fx_bang', 'fx_boom', 'ian_bang', 'ian_boom', 'ian_fash' and 'ianboom'.

0033 <color> <position>
Draw a point at the <position>-th (transformed) position with the color at palette index <color>.
Used for runway lights. Probably the static counterpart to 0096.

0034 <color> <position>
Draw a large point at the <position>-th (transformed) position with the color at palette index <color>.
Used for lights on buildings.

0037 <divisor>
Push a new fog distance on the stack which is divided by <divisor>. It will be popped when the routine returns. This instruction is legacy in TFX3; 'a50' and 'awc_a50' are the only shapes using it and it gives them a buggy appearance.

0039 <unknown> <color> <position0> <position1>
Draw <number ÷ 4> points of the color at palette index <color> between the <position0>-th and <position1>-th position.

003E <opacity> <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded, transparent disc with the color at palette index <color> enclosing the given quad.

007E <opacity> <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded, transparent disc with the color at palette index <color> covering the given quad. If <opacity> equals 0000, the disc is semi-transparent. If <opacity> equals 000E, it is fully transparent. The indices of its underlying quad vertices’ (transformed) positions are given in clockwise order by <position0>, <position1>, <position2> and <position3>.
Used to render low-LOD helicopter rotors. Other values than 0000 and 000E could not yet be tested because we have no untouched glide / Direct3D mode available and the software mode doesn’t support transparency.

0038 <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded disc with the color at palette index <color> covering the given quad. Draws airplane tires.

007D <color> <position0> <position1> <position2> <position3>
Draw a flat-shaded disc with the color at palette index <color> enclosing the given quad. Draws vehicle wheels.

003F <time> <offset>
If (1 << time of day) equals <time>, draw the submesh at <offset> - 2 B.
Used to enable building lights and street lights at 22:00–06:00.

0040 <time> <offset>
0042 <time> <offset>
If a bitwise AND of (1 << time of day) and <time> evaluates nonzero, draw the submesh at <offset> - 2 B.
Used to enable building lights at 20:00–08:00. 0042 is used to enable high-quality glare in TFX3’s 'air_hq' and 'oilrig'.

0043 <time> <offset>
0045 <time> <offset>
If (2 << time of day) - 1 is above or equals <time>, jump <offset> - 2 B.
Used to select shadows and to enable landing gear lights on planes at night.

0048 <index>
Choose parameter <index> as the current active parameter for 0020, 0021 and 0022 instructions.

0049 <yRotation> <xRotation> <zRotation> 0000 0000 0000 0000 0000 0000 <translation> <offset>
A transformation is pushed onto the stack and the routine at <offset> - 2 B is called. The transformation is popped when the routine returns. It consists of (in that order):
 — a rotation about the z axis by 2pi - <zRotation> ÷ 65536 × 2pi
 — a rotation about the y axis by 2pi - <yRotation> ÷ 65536 × 2pi
 — a rotation about the x axis by <xRotation> ÷ 65536 × 2pi
 — a translation to the <translation>-th position.
Used to draw rotated sub-meshes, e.g. turrets. The zeroes in the header are probably scratch space to store three sines and three cosines in order to build a 3×3 rotation matrix.

004B <mask> <offset>
A transformation is pushed onto the stack and the routine at <offset> - 2 B is called. The transformation causes the submesh to always face the viewer. It is popped when the routine returns.
This instruction is used to check if sprites are enabled and, if so, to draw them. Sprites can be smoke puffs or pilot heads. Animated sprites like splash effects, however, use the 0077 instruction instead.

004C <color0|color1> <color2|zero>
Fetch three one-byte color indices for the next Gouraud-shaded triangle.
004E <color0|color1> <color3|color2>
Fetch four one-byte color indices for the next Gouraud-shaded quad.

004D <position0> <position1> <position2>
0080 <position0> <position1> <position2>
Draw a Gouraud-shaded triangle with the last three color palette indices. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1> and <position2>.

004F <position0> <position1> <position2> <position3>
0081 <position0> <position1> <position2> <position3>
Draw a Gouraud-shaded quad with the last four color palette indices. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1>, <position2> and <position3>.

0051 <position> <slot>
0086 <position> <slot>
Draw the mesh at the <slot>th index at the given position. 0051 is common for pylons and weapons; 0086 is exclusively used for rudders in the high-detail F-22 shapes.

0053 <number> <base index> (<x> <y> <z>)[<number>]
Write <number> 3D positions starting at <base index>.

005C <color> <position> <radius>
Draw a flat-shaded sphere of the color at palette index <color> and a radius of <radius> at the <position>-th (transformed) position.
Used for radar domes, simple smoke puffs, heads and other spherical objects.

005D <unknown> <color> <position> <radius>
Draw a semi-transparent flat-shaded sphere of the color at palette index <color> and a radius of <radius> at the <position>-th position.

005F <number> (<color> <position> <radius>)[<number>]
Draw <number> flat-shaded spheres, with of the color at palette index <color> and a radius of <radius> at the <position>-th (transformed) position each.

0060 <number> (<unknown> <color> <position> <radius>)[<number>]
Draw <number> semi-transparent flat-shaded spheres, with of the color at palette index <color> and a radius of <radius> at the <position>-th position each.

0061 <number> <offset>
Transform <number> raw XYZ positions starting at index <offset> for future use.

0062 <index> <x> <y> <z>
Write the given raw XYZ position to the given index.

0063 <x> <y> <z>
Write the next raw XYZ position with the given delta to the lastly-written one.

0064 <x>
Write the next raw XYZ position with the given delta to the lastly-written one.

0065 <y>
Write the next raw XYZ position with the given delta to the lastly-written one.

0066 <z>
Write the next raw XYZ position with the given delta to the lastly-written one.

0067 <x> <y>
Write the next raw XYZ position with the given delta to the lastly-written one.

0068 <x> <z>
Write the next raw XYZ position with the given delta to the lastly-written one.

0069 <y> <z>
Write the next raw XYZ position with the given delta to the lastly-written one.

006A <x> <y> <z> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

006B <x> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

006C <y> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

006D <z> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

006E <x> <y> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

006F <x> <z> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

0070 <y> <z> <index>
Write the raw XYZ position at the given index with the given delta to the lastly-written one.

0071 <position0> <position1> <position2>
Draw a flat-shaded triangle from the (transformed) positions at the given indices (clockwise) with the same color as the last flat-shaded primitive.

0072 <position0> <position1> <position2> <position3>
Draw a flat-shaded quad from the (transformed) positions at the given indices (clockwise) with the same color as the last flat-shaded primitive.

0073 <vertices> (<position>)[<vertices>]
Draw a flat-shaded <vertices>-sided polygon with the same color as the last flat-shaded primitive. It consists of at least three vertices; its (transformed) position’s indices are given in clockwise order.

007F <unknown> <number> (<index> <x> <y> <z>)[<number>] 0000
Write <number> raw XYZ positions.
Used in TFX2 only. <unknown> is 0000 in 'frigate2' and 0004 in 'iftri'. <number> can be zero; in this case, the terminating 0000 is abandoned.

0083 <uBase> <vBase> <uDimension> <vDimension>
Limit texture sampling to the given portion (given in pixels). Out-of-bounds accesses are tiled. This is achieved by computing sample positions through uv % (<uDimension>, <vDimension>) + (<uBase>, <vBase>).
Used to duplicate texture portions over large areas, e.g. single windows over entire buildings.

0084
Use the whole texture for sampling again. Used to terminate 0083 blocks.

008D <number> (<position>)[<number>]
Draw a semi-transparent flat-shaded polygon of the given number of vertices with palette color #152.
Used to draw afterburner triangles in TAW, and to draw quads of unknown purpose in EF2000.

0095 <unknown> <color> <position>
Draw a point at the <position>-th (transformed) position with the color at palette index <color>. <unknown> seems to be legacy; changing it had no visible effect on the game.
Used for lights on planes. Probably the dynamic counterpart to 0033.

0096 <unknown> <color> <position>
Draw a large point at the <position>-th (transformed) position with the color at palette index <color>. <unknown> seems to be legacy; changing it had no visible effect on the game.
Used for lights on planes. Probably the dynamic counterpart to 0034.

0098 <coverage>
Multiply the texture’s coverage with the factor 31 + <coverage> (in the range of [0, 31]).
Used to fade smoke puffs and building shadows.

00A2 <unknown> <position0> <position1> <position2> <position3>
Define a four-sided polygon as a shadow caster for the rest of the shape. The indices of its vertices’ (transformed) positions are given in clockwise order.

00A3 <offset>
If true-color textures are available, jump <offset> - 2 bytes.

00A7 <r> <g> <b>
Enables blending of 0088 textures with the given 8-bpc sRGB color. Available with true-color textures only; usually followed by a 00A8 terminator.

00A8
Disables 00A7.

UNCERTAIN INSTRUCTIONS

0041 <unknown> <offset>
'barracks': Same form as 003f, Is the only test value 128 ???

0075 <position>
Transform the position at index <position>.

0076 <offset>
If ???, jump <offset> - 2 bytes.
'abtw_1ra': (assume yes)

007B <offset>
If ???, jump <offset> - 2 bytes.
'abtw_1ra': (assume yes)

007C <offset>
Jump <offset> - 2 bytes. Enables shading of the F-22 canopy (not drawn if not jumping).

0087 <offset>
If ???, jump <offset> - 2 bytes. Seems to enable or disable planes.
'a101': (assume yes)

0093 <offset>
If ???, jump <offset> - 2 bytes. Seems to enable or disable terrain.
'abtw_1ra': (assume yes)

0094 <unknown>[2]
'awc_f14': May need to move to unknown jumps section ???
http://community.combatsim.com/topic/25920-taw-terrain-format/page__view__findpost__p__5124540

009D <position0> <position1> <position2>
Draw a triangle. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1> and <position2>. Whether the triangle is flat-shaded, Gouraud-shaded or textured depends on the material mode set by the last 009F instruction.

009E <position0> <position1> <position2> <position3>
Draw a quad. The indices of its vertices’ (transformed) positions are given in clockwise order by <position0>, <position1>, <position2> and <position3>. Whether the triangle is flat-shaded, Gouraud-shaded or textured depends on the material mode set by the last 009F instruction.

009F <unknown> <surface> <type>
Fetch the next triangle’s or quad’s material. Whether it is flat-shaded, Gouraud-shaded or textured depends on the global 'BUILD_TEXTURES' flag as well as on the instruction’s type:
 • with BUILD_TEXTURES enabled, the rendering mode is read from 'red****.ini'.
 • with BUILD_TEXTURES disabled, the rendering mode depends on the instruction’s type:
   — 0103 <color>: one color is fetched for a flat-shaded quad.
   — 0301 <color>[3]: three colors are fetched for a Gouraud-shaded triangle.
   — 0401 <color>[4]: four colors are fetched for a Gouraud-shaded quad.
   — 0900 FFFF (<U> <V>)[4]: four texture positions are fetched for a textured quad.

UNKNOWN INSTRUCTIONS

002C <unknown>[6]
Used in EF2000 ('frigate2') only.

0036 <unknown>
Used in EF2000’s 'apc2' only.

004A <unknown>
Probably some vertex operation. Changing the value did not have any visible effect on the game. Postponed.

0085 <unknown>
Used in EF2000’s 'basecol' only.

0052 <unknown>[3]
"I can change this line: 0052000e000c000e to 0052000000000000 or 0052ffffffffffff and it makes absolutely no visible difference in software or Glide mode. So, on this evidence, 0052 does nothing in TAW."
http://community.combatsim.com/topic/25920-taw-terrain-format/page__view__findpost__p__5124406
http://community.combatsim.com/topic/25920-taw-terrain-format/page__view__findpost__p__5124457

0054
'newhoriz': 'Found at start of certain files. Ignore unless it expects a terminator.'
http://community.combatsim.com/topic/25920-taw-terrain-format/page__view__findpost__p__5124626

0074
Does not occur in TFX3. Used in EF2000’s 'cptefa_h', 'cpttest', 'efa_hold', 'efa_scl', 'efa_shad', 'efacpt', 'efacpt_4', 'efacpt_s' and 'efatast'.

008B
Does not occur in TFX3. Used in EF2000’s 'efa', 'efa_egl', 'efa_ian', 'new_efa' and 'new_efa1'.

008C
Does not occur in TFX3. Used in EF2000’s 'efa', 'efa_egl', 'efa_ian', 'new_efa' and 'new_efa1'.

0097 <unknown>[2]
'ian_*'

Sorry for the wall of text, but I can't see any spoiler tags in the new forum layout …

Link to comment
Share on other sites

P.S.: We never fully decoded the time of day opcodes. They work mostly well in TAW (apart from weird transparency issues in oil refineries), but they fail completely in EF2000 (where they sometimes cause Level of Detail transitions and shapes being drawn twice or thrice).

I've long had the idea of loading EF2000 and TAW concurrently in TFXplorer (so that you can fly the F-22 around Norway), but this was one of the issues holding me back. So, if you're bored … ;)

Link to comment
Share on other sites

Yes, transformation opcode is in and Z order is correct via reordered vertices. That is the true color version using 00A7 / 00A8 and I had to disable the 007C shader to maintain transparency.  I have an older version, I previously constructed using the 64 x 64, 32 bit textures, that doesn't become opaque with the shader. It looks like your posted image, with the faces delineated, though, but still may give another canopy option. Currently initiating testing on 002C in place of 007F, maybe something new will shake-out.

Link to comment
Share on other sites

  • 2 weeks later...
  • 4 years later...
On 10/24/2015 at 12:55 PM, Krycztij said:

 

The canopy drawing is more complicated than I expected, too — the transparent and solid parts are on the same triangle and just use different textures. Just changing texture color is not enough; I need to write a shader for that :(

 

 

I'm doing some work in TAW on Transparency and modifications of the canopy. Can you recall the specifics of how TAW draws opaque (?) an transparent on the same triangle ?

Link to comment
Share on other sites

17 hours ago, DrKevDog said:

I'm doing some work in TAW on Transparency and modifications of the canopy. Can you recall the specifics of how TAW draws opaque (?) an transparent on the same triangle ?

 

It’s two different draw instructions like you mentioned here:

On 10/24/2015 at 8:30 PM, DrKevDog said:

I thought the transparent and solid parts also used a different draw call:

Example:

004700060003005E00B1007C00B1007C00BF00880003006300F300C2 (transparent)

004700480003000000000004001800000018008E0003006300F300C2 (solid-mask)

Note the solid orange canopy base:canopy2_zpsw0wt3ccf.jpg

canopy3_zpsqxih0xpy.jpg

 

I disabled 0088 in my code and suddenly the canopy would not draw anymore, but its base (the orange part in your screenshots) still would. So there’s 0088 for the semi-transparent part and some other instruction to draw the opaque parts with 1-bit alpha.

Link to comment
Share on other sites

Hmmm, I'll have to look at it some more because I thought I found that 0088 was used by the open canopy code and 008E for the closed. I do recall that, years ago when I converted the F22 skin to 24-bit color, using the AGP, I could only keep the game from crashing by loading the texture for the base strip from slot 201 (C8), exclusively, and I never figured out why. I still have all my notebooks from those days, I will have to find out if there is any help in there.

Link to comment
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.

 Share

×
×
  • Create New...