Wing Commander Toolbox

UnnamedCharacter

2nd Lieutenant
Does anyone know, which file contains the sound effects of WC2?
They are within the WING2.TIM file. The file has three blocks dividing the effects by audio format: MIDI, SoundBlaster, PC Speaker. If you unpack the TIM file and view the content of individual files (ex: WING2.TIM-Block000Midi-Audio009.tim), you will see the effect name.

There is also the file FX.000 which as to do with sound effects, but I have no idea what it does. It seems specific to the cinematic scenes only.
 

delMar

Rear Admiral
They are within the WING2.TIM file. The file has three blocks dividing the effects by audio format: MIDI, SoundBlaster, PC Speaker. If you unpack the TIM file and view the content of individual files (ex: WING2.TIM-Block000Midi-Audio009.tim), you will see the effect name.

There is also the file FX.000 which as to do with sound effects, but I have no idea what it does. It seems specific to the cinematic scenes only.
Nice.
What do I need to do to have files that I can actually play in VLC for example?
Just changing the file extension doesn't work :)

I'm especially interested in the SoundBlaster files, btw
 

UnnamedCharacter

2nd Lieutenant
Just changing the file extension doesn't work.
I don't think these files are "playable". My guess is these files are patches for an audio system. You will probably have more luck experimenting with the Roland MT-32 sounds within the game as there seems to be good tooling for these.
 

delMar

Rear Admiral
I don't think these files are "playable". My guess is these files are patches for an audio system. You will probably have more luck experimenting with the Roland MT-32 sounds within the game as there seems to be good tooling for these.
Alright, thanks.

Hm, speech files are in .voc format.
Maybe these are just .voc files without the header...
 

delMar

Rear Admiral
I wanted to take a look into cinematics.
For reverse engineering, it's best to start with a piece that's small and (supposedly) easy to understand.

I looked a bit into INCIDENT.S00, especially into INCIDENT.S00-ContainerBlock078-ContainerGroup-PlaneGroup-ScriptGroup-OffsetChunk.bin

ContainerBlock 078 deals with the short cutscene right after clicking "New Game" up to destroying the Tiger's Claw.
Prince Thrakath talking to the Emperor is not part of this anymore.

So, what we see in this cinematic is
  • A background of stars
  • The words "ORIGIN Presents..."
  • "A Chris Roberts game"
  • "Directed by Stephen Beeman"
This is far from complete, but I just wanted to keep track of what I'm doing. And everyone loves updates, right? :)

The content of the .bin file mentioned above is as follows
Code:
02 00 FF FF FF FF 04 00 00 00 79 00 08 79 00 09 79 00 0A 23 0E FE FF
All the relevant XML is shown below.

I found out the following about the .bin file:
  • I think the 02 00 at the beginning refers to "backdrop" and "bigscreen" of PlaneGroup/ScriptGroup
  • The FF FF FF FF seems to be some kind of placeholder. I don't think it's actually interpreted.
  • 04 00 00 00 might refer to 4 blocks that are following. These 4 blocks are as follows
  1. 79 00 08
  2. 79 00 09
  3. 79 00 0A
  4. 23 0E FE FF
The 08, 09 and 0A at the end refer to SpriteGroup/ScriptGroup SymbolItems and describe the index of the Sprite.
If you replace the 08 with 10 (which is actually 16, as it's all hex numbers here), you wouldn't see the background of stars scrolling up, but the sprite holding the word "game" from "A game by Chris Roberts".
So, 08 is tigerscreen, 09 is starfield, and 0A is starfield2
starfield and starfield2 actually refer to the same image (the second image stored in field.v00).
I have no idea, what 23 0E FE FF mean.
Changing 79 to 78 or 80 crashed the game
Changing the 23 0E to anything else crashed the game.
I think the FE FF is just some kind of terminator to end the datablock

I also checked INCIDENT.S00-ContainerBlock078-ContainerGroup-SpriteGroup-ScriptGroup-OffsetChunk.bin

upload_2018-4-13_20-52-37.png


The 16 00 at the beginning seems to be an offset to when data actually starts (FF FF x 16)
After that, we have numbers like 38 00 00 00 3F 00 00 00 etc. 14 of them in total.
14 matches the SpriteGroup/ScriptGroup SymbolItems, when ignoring the __slot ones.
What could these 38, 3F, 45 mean?
Well, I think they are lengths for the datablocks that are following these 14 values.
I'm pretty sure they match the list of sprites again.
The blocks are:
Code:
24 00 46 25 90 01 47 23 0E FE FF #tigerscreen
24 00 46 24 00 47 23 0E FE FF #starfield
24 00 46 25 C8 00 47 23 0E FE FF #starfield2

24 3C 46 24 40 47 9E 00 78 01 00 00 03 23 0E FE FF #origin
25 8C 00 46 24 40 47 9E 00 78 01 01 00 03 23 0E FE FF #presents

24 32 46 24 46 47 9E 00 78 01 02 00 03 23 0E FE FF #asprite
24 47 46 24 46 47 9E 00 78 01 03 00 03 23 0E FE FF #chris
25 83 00 46 24 46 47 9E 00 78 01 04 00 03 23 0E FE FF #roberts
25 DC 00 46 24 49 47 9E 00 78 01 05 00 03 23 0E FE FF #game

24 5A 46 24 37 47 9E 00 78 01 06 00 03 23 0E FE FF #directed
25 BE 00 46 24 3A 47 9E 00 78 01 07 00 03 23 0E FE FF #by
24 46 46 24 4F 47 9E 00 78 01 08 00 03 23 0E FE FF #stephen
25 A0 00 46 24 4C 47 9E 00 78 01 09 00 03 23 0E FE FF #beeman

24 14 46 24 03 47 9E 00 78 01 00 00 02 23 0E FE FF #logosprite
To take one example, I was pretty sure I figured out some more details:
Code:
24 32 46 24 46 47 9E 00 78 01 02 00 03 23 0E FE FF #asprite
32 could be the x-position of the sprite. It matches my measures from screenshots.
Changing that value actually moved the sprite, but just to x-pos=0, not to the position I specified... (see two screenshots attached to see the result)
47 could be the y-position, but just changing it didn't show the expected results.
These x and y values match the coordinates of all 14 sprites, so I'm pretty convinced it's something related to that.
23 0E FE FF is at the end of each line, just like in the other .bin file I described before.

In general: FileEntryItem-Identifier in FileEntryItem always refers to the index of FileEntryNameItems in FileChunk.Names.
So, Block="0" Identifier="0" refers to the first entry in tiger.v00 (which one that is can be read in tiger.v00.xml when using xmlunpack on it)

As I said, not too much to see here, but in case anyone else is looking into this, I wanted to share my findings.

Things still missing:
  • investigating SequenceGroup
  • investigating SceneGroup
They probably keep information about timings, actual actions (like scroll up, fade-in, display, remove, ...)

@UnnamedCharacter let me know if you prefer things like these to be in a separate thread.

Code:
  <ContainerBlock.Chunks>
      <ContainerGroup>
        <TextGroup>
          <SymbolChunk>
            <SymbolChunk.Items>
              <SymbolItem Text="TCS Tiger's Claw.&#xA;On attack approach to K'Tithrak Mang,&#xA;Kilrathi Sector HQ." />
            </SymbolChunk.Items>
          </SymbolChunk>
        </TextGroup>
        <ShapeGroup>
          <FileChunk>
            <FileChunk.Entries>
              <FileEntryItem Block="0" Identifier="0" />
              <FileEntryItem Block="1" Identifier="1" />
              <FileEntryItem Block="0" Identifier="2" />
              <FileEntryItem Block="0" Identifier="3" />
            </FileChunk.Entries>
            <FileChunk.Names>
              <FileEntryNameItem Name="tiger.v00" />
              <FileEntryNameItem Name="field.v00" />
              <FileEntryNameItem Name="logo.v00" />
              <FileEntryNameItem Name="titles.v00" />
            </FileChunk.Names>
          </FileChunk>
        </ShapeGroup>
        <FilmGroup>
          <FileChunk>
            <FileChunk.Entries>
              <FileEntryItem Block="48" Identifier="0" />
            </FileChunk.Entries>
            <FileChunk.Names>
              <FileEntryNameItem Name="series.s00" />
            </FileChunk.Names>
          </FileChunk>
        </FilmGroup>
        <SpriteGroup>
          <ScriptGroup>
            <OffsetChunk file="INCIDENT.S00-ContainerBlock078-ContainerGroup-SpriteGroup-ScriptGroup-OffsetChunk.bin" />
            <SymbolChunk>
              <SymbolChunk.Items>
                <SymbolItem Text="__slot0" />
                <SymbolItem Text="__slot1" />
                <SymbolItem Text="__slot2" />
                <SymbolItem Text="__slot3" />
                <SymbolItem Text="__slot4" />
                <SymbolItem Text="__slot5" />
                <SymbolItem Text="__slot6" />
                <SymbolItem Text="__slot7" />
                <SymbolItem Text="tigerscreen" />
                <SymbolItem Text="starfield" />
                <SymbolItem Text="starfield2" />
                <SymbolItem Text="origin" />
                <SymbolItem Text="presents" />
                <SymbolItem Text="asprite" />
                <SymbolItem Text="chris" />
                <SymbolItem Text="roberts" />
                <SymbolItem Text="game" />
                <SymbolItem Text="directed" />
                <SymbolItem Text="by" />
                <SymbolItem Text="stephen" />
                <SymbolItem Text="beeman" />
                <SymbolItem Text="logosprite" />
              </SymbolChunk.Items>
            </SymbolChunk>
          </ScriptGroup>
        </SpriteGroup>
        <PlaneGroup>
          <ScriptGroup>
            <OffsetChunk file="INCIDENT.S00-ContainerBlock078-ContainerGroup-PlaneGroup-ScriptGroup-OffsetChunk.bin" />
            <SymbolChunk>
              <SymbolChunk.Items>
                <SymbolItem Text="backdrop" />
                <SymbolItem Text="bigscreen" />
              </SymbolChunk.Items>
            </SymbolChunk>
          </ScriptGroup>
        </PlaneGroup>
        <SequenceGroup>
          <ScriptGroup>
            <OffsetChunk file="INCIDENT.S00-ContainerBlock078-ContainerGroup-SequenceGroup-ScriptGroup-OffsetChunk.bin" />
            <SymbolChunk>
              <SymbolChunk.Items>
                <SymbolItem Text="removeall" />
                <SymbolItem Text="showslot" />
                <SymbolItem Text="hideslot" />
                <SymbolItem Text="delmediumslot" />
                <SymbolItem Text="setupmediumslot" />
                <SymbolItem Text="mediumshot" />
                <SymbolItem Text="setupuniform" />
                <SymbolItem Text="setupbackdrop" />
                <SymbolItem Text="setupbackground" />
                <SymbolItem Text="initshardrun" />
                <SymbolItem Text="talking" />
                <SymbolItem Text="settalker" />
                <SymbolItem Text="vidit" />
                <SymbolItem Text="printit" />
                <SymbolItem Text="closeup" />
                <SymbolItem Text="restoredefaultfont" />
                <SymbolItem Text="removeperson" />
                <SymbolItem Text="addplanet" />
                <SymbolItem Text="removeplanet" />
                <SymbolItem Text="narrating" />
                <SymbolItem Text="doshow" />
                <SymbolItem Text="sidewaysthrusters" />
                <SymbolItem Text="__flicker__" />
              </SymbolChunk.Items>
            </SymbolChunk>
          </ScriptGroup>
        </SequenceGroup>
        <SceneGroup>
          <ScriptGroup>
            <OffsetChunk file="INCIDENT.S00-ContainerBlock078-ContainerGroup-SceneGroup-ScriptGroup-OffsetChunk.bin" />
            <SymbolChunk>
              <SymbolChunk.Items>
                <SymbolItem Text="doit" />
              </SymbolChunk.Items>
            </SymbolChunk>
          </ScriptGroup>
        </SceneGroup>
      </ContainerGroup>
    </ContainerBlock.Chunks>
  </ContainerBlock>
 

Attachments

UnnamedCharacter

2nd Lieutenant
let me know if you prefer things like these to be in a separate thread
Yes, thank you. I think all this information could become a long thread indeed. Hopefully it will become a very long thread as there is a lot of information to be compiled.

I have been making some progress as well on this. From what I have gathered, the game appears to use a Stack-Based Bytecode Interpreter; it pushes/pops values on a stack. I have reformatted your code examples to show the structure of *.bin files. See also previous post for *.bin file header details.

Code:
// INCIDENT.S00-ContainerBlock078-ContainerGroup-PlaneGroup-ScriptGroup-OffsetChunk.bin
//
// Entries:   2
// Offsets:       -1     4

// entry 0 (empty)

// entry 1
79 00 08
79 00 09
79 00 0A
23
0E FEFF
Code:
// INCIDENT.S00-ContainerBlock078-ContainerGroup-SpriteGroup-ScriptGroup-OffsetChunk.bin
//
// Entries:  22
// Offsets:       -1    -1    -1    -1    -1    -1    -1    -1    56    63    69    76    89   103   116   129   143   157   170   184   197   211

// entry 0-7 (empty)

// entry 8
24 00       // push.i1   0 ( 8-bit integer)
46          // set x
25 9001     // push.i2 400 (16-bit integer)
47          // set y
23
0E FEFF

// entry 9
...
 
Last edited:

lskovlun

Veteran Spaceman
Hi everyone, I'm new here. I've been spending some time writing a disassembler for the SERIES.xxx, INCIDENT.xxx, GAMEFLOW.xxx and CAMPAIGN.xxx files in WC2, and it actually works pretty well at this point. I wanted to try out the WC Toolbox to make sure we're on the same page regarding terminology and such, but I can't get WC Toolbox to work with my WC2 files; I get an "unsupported source file" error (tried with both SERIES.S00 and INCIDENT.S00). So with that caveat out of the way, on to my findings.

I haven't read delMar's monster post in full yet, but I have a few comments. While starting with small pieces is indeed a good idea, the stuff in the INCIDENT files require a good understanding of the animation system in WC2, whereas SERIES is mostly repeats of the same things (set up some variables, print some dialogue, make a subroutine call to INCIDENT, and little else). Very repetitive, and therefore very good to start with. In particular, the opening scene that delMar refers to requires understanding of scrolling planes to understand the code. Knowledge that I don't have, so I use opcode names like SET_SPRITE_FIELD_2B and such. I also don't have an assembler for these files yet, so I can't experiment.

Anyway, a disassembled extract from SERIES.S00 reads:
Code:
Contents of sprite section of entry point 0:
Contents of plane section of entry point 0:
Contents of sequence section of entry point 0:
Talk1:
0070 YIELD
0071 MUSIC1 0
0074 MUSIC2 12
0076 MUSIC3 music.r00(41)
0078 MUSIC4 music.r00(41)
007a RUN_SEQUENCE removeall
007c GET_TEXT "  "
007f RUN_SCENE incident.s00(78)
0081 PUSH_CONSTB 0
0083 MANIP_SKIP
0084 MUSIC1 0
0087 MUSIC2 12
0089 MUSIC3 music.r00(53)
008b MUSIC4 music.r00(53)
008d PUSH_CONSTB 16
008f POP_SET_GLOBAL 297
0092 PUSH_CONSTB -1
0094 POP_SET_GLOBAL 296
0097 RUN_SEQUENCE initshardrun
0099 PUSH_GLOBAL 276
009c POP_SET_GLOBAL 295
009f PUSH_CONSTW 200
00a2 POP_SET_GLOBAL 276
00a5 RUN_SEQUENCE settalker
00a7 PUSH_GLOBAL 295
00aa POP_SET_GLOBAL 276
00ad RUN_SEQUENCE removeall
00af GET_TEXT "K'Tithrak Mang \n Kilrathi Sector HQ"
00b2 RUN_SCENE incident.s00(69)
00b4 PUSH_CONSTB 3
00b6 POP_SET_GLOBAL 388
00b9 PUSH_CONSTB 16
00bb POP_SET_GLOBAL 297
00be PUSH_CONSTB -1
00c0 POP_SET_GLOBAL 296
00c3 RUN_SEQUENCE initshardrun
00c5 PUSH_CONSTB 0
00c7 PRELOAD_SPEECH speech.s00(0)
00c9 PUSH_CONSTB 0
00cb POP_SET_GLOBAL 761
00cf PUSH_GLOBAL 276
00d2 POP_SET_GLOBAL 295
00d5 PUSH_CONSTB 26
00d7 POP_SET_GLOBAL 276
00da RUN_SEQUENCE settalker
00dc PUSH_GLOBAL 295
00df POP_SET_GLOBAL 276
00e2 RUN_SEQUENCE removeall
00e4 GET_TEXT "I will speak with Prince Thrakhath alone.\nGuards, you are dismissed."
00e7 RUN_SCENE incident.s00(49)
As you can see, a large part of the task ahead is documenting the variable names. (PUSH_GLOBAL, POP_SET_GLOBAL). They are needed because subroutine calls cannot pass arguments in any other way, and they contribute greatly to the structure of the code.
Also, the opcode names are not set in stone at all.
 
Last edited:

UnnamedCharacter

2nd Lieutenant
@lskovlun

You are way ahead than I am; the Toolbox has no support for the bytecode data.

As for the "unsupported source file" error on SERIES.S00 and INCIDENT.S00, you might not be using the latest version, otherwise the following should work:
WC2ToolsCmd.exe extract INCIDENT.S00​

Nice work, keep it up.
 

UnnamedCharacter

2nd Lieutenant
I put together a simple assembler/disassembler. Although it lacks the sophistication demonstrated by @lskovlun, it does have the basic functionality of managing jump targets. Unfortunately, it does have problems with two files, when disassembled they will not re-assemble:

SERIES.S00-ContainerBlock005-ContainerGroup-SequenceGroup-ScriptGroup-OffsetChunk.asm
error: undefined symbol: _08b2

SERIES.S00-ContainerBlock013-ContainerGroup-SequenceGroup-ScriptGroup-OffsetChunk.asm
error: undefined symbol: _2442​

The problem are jump values that appear to be too large, they jump beyond the end of the file. For the time, avoid these two files.

In any case, here are some examples of the disassembly:

Code:
; SERIES.S00-ContainerBlock000-ContainerGroup-SceneGroup-ScriptGroup-OffsetChunk.asm

.entry ;   0
  _0000:  c035                                  ; yield
  _0001:  c036          15                      ; push constant, byte
  _0003:  c129     
  _0004:  c038           4                      ; get global[<uintvar:index>]
  _0006:  c036           0                      ; push constant, byte
  _0008:  c027                                  ; ==
  _0009:  c015       _0011                      ; jz
  _000c:  c136          22                      ; run sequence
  _000e:  c014       _0052                      ; jmp
  _0011:  c038           4                      ; get global[<uintvar:index>]
  _0013:  c036           1                      ; push constant, byte
  _0015:  c027                                  ; ==
  _0016:  c015       _001e                      ; jz
  _0019:  c136          23                      ; run sequence
  _001b:  c014       _0052                      ; jmp
  _001e:  c038           4                      ; get global[<uintvar:index>]
  _0020:  c036           2                      ; push constant, byte
  _0022:  c027                                  ; ==
  _0023:  c015       _002b                      ; jz
  _0026:  c136          24                      ; run sequence
  _0028:  c014       _0052                      ; jmp
  _002b:  c038           4                      ; get global[<uintvar:index>]
  _002d:  c036           3                      ; push constant, byte
  _002f:  c027                                  ; ==
  _0030:  c015       _0038                      ; jz
  _0033:  c136          25                      ; run sequence
  _0035:  c014       _0052                      ; jmp
  _0038:  c038           4                      ; get global[<uintvar:index>]
  _003a:  c036           4                      ; push constant, byte
  _003c:  c027                                  ; ==
  _003d:  c015       _0045                      ; jz
  _0040:  c136          26                      ; run sequence
  _0042:  c014       _0052                      ; jmp
  _0045:  c038           4                      ; get global[<uintvar:index>]
  _0047:  c036           5                      ; push constant, byte
  _0049:  c027                                  ; ==
  _004a:  c015       _0052                      ; jz
  _004d:  c136          27                      ; run sequence
  _004f:  c014       _0052                      ; jmp
  _0052:  c131           0,     0,   255
  _0056:  c014       _0000                      ; jmp
Code:
; INCIDENT.S00-ContainerBlock000-ContainerGroup-SequenceGroup-ScriptGroup-OffsetChunk.asm

.entry ;  22
  _0000:  c035                                  ; yield
  _0001:  c036           0                      ; push constant, byte
  _0003:  c036           0                      ; push constant, byte
  _0005:  c110           3
  _0007:  c109           8
  _0009:  c136          20                      ; run sequence
  _000b:  c037         300                      ; push constant, word
  _000e:  c107                                  ; set sequence field, +23, timer
  _000f:  c106                                  ; get sequence field, +23, timer
  _0010:  c015       _0016                      ; jz
  _0013:  c014       _000f                      ; jmp
  _0016:  c153           0
  _0018:  c034                                  ; return value to zero
  _0019:  c014       _0000                      ; jmp
And here is a functional example, changed the text and inserted two instructions:

WC2ToolsCmd.exe xmlunpack INCIDENT.S00
WC2Assembler.exe INCIDENT.S00-ContainerBlock078-*.bin

WC2Assembler.exe INCIDENT.S00-ContainerBlock078-*.asm
WC2ToolsCmd.exe xmlpack INCIDENT.S00.XML​

Code:
<!-- INCIDENT.S00.XML -->

  <ContainerBlock><!-- 078 -->
    <ContainerBlock.Chunks>
      <ContainerGroup>
        <TextGroup>
          <SymbolChunk>
            <SymbolChunk.Items>
              <SymbolItem Text="TCS Tiger's Claw.&#xA;Beautiful ship, shame it will be destroyed.&#xA;Kilrathi Sector HQ." />
            </SymbolChunk.Items>
          </SymbolChunk>
  ...
Code:
; INCIDENT.S00-ContainerBlock078-ContainerGroup-SequenceGroup-ScriptGroup-OffsetChunk.asm

.entry ;  22, position:     94
  _0000:  c119           1                      ; link
  _0002:  c035                                  ; yield
  
          c037         212  ; push value
          c148           3  ; fill canvas (3, subtitle) using the pushed color (212)
  
  _0003:  c031           9                      ; select sprite
  _0005:  c158           0
  _0007:  c120           1,     0,     0,     1 ; set sprite data
  _000c:  c031          10                      ; select sprite
  _000e:  c158           0
...
WC2TCDestruction2.png
 

Attachments

UnnamedCharacter

2nd Lieutenant
Work on the toolbox has continued and this release begins support for Privateer 1.

This update adds the ability to create or edit many of the Privateer file types: IFF, PAK, PAL, PFC, SHP, TRE, VPF, VPK; it expands the number of image formats supported: BMP, GIF, PNG, and TIFF; and also provides the ability to create compressed files where appropriate. All of this new functionality is specific to the Privateer tools.

See first post for the file attachment.

sample1.png
sample2.png


There are major changes introduced in Privateer, such as the extensive use of files within files, the use of many different color palettes, and the move toward the Interchange File Format (IFF). With all these changes, I ended up taking a completely different approach for the Privateer tooling; it is actually modeled after the Prophecy development tools. I am leveraging the overall design approach used in the Prophecy tools such as the use of custom script files to guide the creation of new files. I am also making use of the existing Extended MakeIFF compiler (XMIFF) an old DOS program from the Prophecy tools for creating IFF files. All of this has the obvious benefit of saving me the effort of creating similar functionality.

See below for a series of posts describing each command, the custom scripts, and how to use the Extended MakeIFF compiler (XMIFF).


intro1.PNG
intro2.PNG


intro3.PNG
intro4.PNG
intro5.PNG
intro6.PNG
intro7.PNG
 
Last edited:

UnnamedCharacter

2nd Lieutenant
Privateer 1 Tools Commands: tree / untree

You can use these commands to create a tree (TRE) file from imported files, or reverse a tree file into exported files.

A tree file is a container file which internally uses a directory structure mapping the file paths to file content.

To unmake a tree file:

Priv1ToolsCmd untree source [destination]

Priv1ToolsCmd untree SPACE.TRE​

This will output the content of each file into an actual directory structure, create a padding file, and a script to run which will remake the tree file.

Code:
outputfile SPACE.TRE

padding SPACE.TRE.PADDING

file ..\..\DATA\MISSIONS\S7MB.IFF
file ..\..\DATA\MISSIONS\S5MD.IFF
file ..\..\DATA\MISSIONS\S5MC.IFF
file ..\..\DATA\MISSIONS\S5MB.IFF
...
The file paths are prefixed because the tree file expects it, but these prefixes are ignored when finding the actual files. As for the padding file, I have no idea what this padding is for, but just in case it is useful I preserve it.

To make a tree file:

Priv1ToolsCmd tree script

Priv1ToolsCmd tree SPACE.TRE.SCR​
 
Last edited:

UnnamedCharacter

2nd Lieutenant
Privateer 1 Tools Commands: pack / unpack

You can use these commands to create a pack (PAK) file from imported files, or reverse a pack file into exported files.

A pack file is a container file which divides the content internally as individual packets. It is analogous to a DataFile in the tools for WC1/2. Pack files may use different file extensions, such as: VPK for VoicePack (Male), VPF for VoicePackFemale.

To unmake a pack file:

Priv1ToolsCmd unpack source [destination]

Priv1ToolsCmd unpack DATA\OPTIONS\CU.PAK​

This will output each packet as a file, and a script to run which will remake the pack file.

Code:
outputfile CU.PAK

flag -32
file CU.PAK-Packet000.PCK
flag -32
file CU.PAK-Packet001.PCK
flag -32
file CU.PAK-Packet002.PCK
...
The flag value indicates the format of the packet, such as compressed.

To make a pack file:

Priv1ToolsCmd pack script

Priv1ToolsCmd pack CU.PAK.SCR​
 
Last edited:

UnnamedCharacter

2nd Lieutenant
Privateer 1 Tools Commands: palette / unpalette

You can use these commands to create a palette (PAL) file from an image, or reverse a palette file into an image.

A palette file obviously contains the color values of a palette, but instead of 8-bit per color channel (RGB), the values are in 6-bit form, as expected by VGA. The conversion to/from an image will transformed the values to/from 8-bit, making the colors display as expected. There are also two variations, a full palette of 256 colors, or a half palette of 128 colors.

To unmake a palette file:

Priv1ToolsCmd unpalette source [destination] [/format:(BMP|GIF|PNG|TIF)]

Priv1ToolsCmd unpalette DATA\PALETTE\SPACE.PAL​

This will output an image representing the palette, and a script to run which will remake the palette file.

palette1.PNG


Code:
outputfile SPACE.PAL

composite   0 256 # startindex colorcount

inputfile SPACE.PAL.PNG
Since palettes can be joined, there is a small amount of metadata to indicate how to combine them; the start index and the color count of a composite palette.

To make a palette file:

Priv1ToolsCmd palette script

Priv1ToolsCmd palette SPACE.PAL.SCR​
 
Last edited:

UnnamedCharacter

2nd Lieutenant
Privateer 1 Tools Commands: shape / unshape

You can use these commands to create a shape (SHP) file from encoded images, or reverse a shape file into decoded images.

A shape file is a container file which divides the content internally as individual shapes. It is analogous to an ImageBlock in the tools for WC1/2. An image must be specified to be used as a palette since shapes contain no color values.

To unmake a shape file:

Priv1ToolsCmd unshape source [destination] [/format:(BMP|GIF|PNG|TIF)] /palette:image

Priv1ToolsCmd unshape DATA\OPTIONS\JOYCALIB.SHP /p:JOYCALIB.PAL.PNG​

This will output each shape as an image, and a script to run which will remake the shape file.

shape1.PNG


Code:
outputfile JOYCALIB.SHP

origin   0  59
inputfile JOYCALIB.SHP-Shape000.PNG
origin   0   4
inputfile JOYCALIB.SHP-Shape001.PNG
origin   0   4
inputfile JOYCALIB.SHP-Shape002.PNG
...
The origin is the xy-coordinates of the image which will often times be used as the insertion point.

To make a shape file:

Priv1ToolsCmd shape script

Priv1ToolsCmd shape JOYCALIB.SHP.SCR​
 
Last edited:

UnnamedCharacter

2nd Lieutenant
Privateer 1 Tools Command: unmake

You can use this command to reverse various data files (IFF, PFC, etc) into a custom format.

To unmake a data file:

Priv1ToolsCmd unmake source [destination] [/encoding: (code page|name)] /template:(Conversation|Interchange|Palette)​

To unmake a conversation file:

Priv1ToolsCmd unmake DATA\CONV\CARGO.PFC /t:Conversation​

This will output a code file which can be processed by XMIFF to remake the data file.

Code:
char 0
char[9] "rand_npc"
char[9] "normal"
char[9] "shpdlr_1"
short 159,  9 // xy
cstring "Good choice, but far be it for me to pass up a sale..."
char 224 // palette index

char 0
char[9] "rand_npc"
char[9] "normal"
char[9] "shpdlr_1"
short 159,  9 // xy
cstring "...I can't afford to take advantage of a customer."
char 224 // palette index
...
To unmake an interchange file:

Priv1ToolsCmd unmake DATA\CONV\RUMORS.IFF /t:Interchange​

This will output a code file which can be processed by XMIFF to remake the data file.

Code:
FORM "RUMR"
{
    CHUNK "CHNC"
    {
        short 20 // chance buzzoff
        short 40 // chance base
        short 40 // chance plot
        short 40 // chance general
    }
}
To make a data file (from DOSBox if in 64-bit Windows):

XMIFF CARGO.XMF CARGO.PFC

XMIFF RUMORS.XMF RUMORS.IFF​
 
Last edited:

UnnamedCharacter

2nd Lieutenant
The following is an example for extracting the external ship views. Since the game data is divided among multiples files, and is contained in files within files, a multi step process is used.

We start by extracting the files from two tree files:

Priv1ToolsCmd.exe untree MIDGAMES.TRE
Priv1ToolsCmd.exe untree OBJECTS.TRE​

Next we convert a palette file into an image:

Priv1ToolsCmd.exe unpalette DATA\PALETTE\SPACE.PAL​

Next we unmake an interchange file since it contains the shapes we need:

Priv1ToolsCmd.exe unmake DATA\APPEARNC\BRDSWORD.IFF /t:Interchange​

Finally, we convert the shapes into images:

Priv1ToolsCmd.exe unshape BRDSW000.* /p:SPACE.PAL.PNG​


example-ship1.PNG
example-ship2.PNG
example-ship3.PNG
 
Top