📜 ⬆️ ⬇️

Parse "Opposition - Military Chronicle" (1996-1997, Doc)

Introduction


Good to everyone, I want to tell you about the warm and lamp strategy of childhood - Confrontation. The game was released in 1996-98 by our Russian company Doc.
The game is a real-time strategy game about the second world war. After many years, I decided to first go through it and record the passage, and then try to maximize the enjoyment of the game, unpacking resources and trying to understand the game logic.

Under the cut, I will describe the process of extracting music, graphics and a little bit I will not reach the map editor.
Also in the description will be a reference to the 8-bit color palette, pseudo archives, RLE-compression and a bit of a HEX editor. In the code itself, I only looked at the decoding algorithm for images compressed with RLE.

image

The original plan was to get the music and turn off the fog of war, then got a little carried away and unpacked 9 files (.ADW, .DAW, .RUS).
')
I play and recommend the full 2v1 version ( Confrontation: Military Chronicle ) with five cd-audio tracks, that is, a full rip of the latest version of the game all-in-one.
If I had the opportunity, I would have bought it again, since my original disc, purchased in 98g, was not preserved.

Music


The obvious and simple solution is to run the game under the dosbox and record all the music, which I did in the first place. Playlist with music .

Then I thought it was wrong. It turns out that this music is not original, but passed through dosbox filters. Decided to unpack to wav state, taking the original data.
Opened music.dat file in winhex. Since there are voice inserts in the music, I assumed that there is a digital stream.
Thanks to the old-games forum where I was told that most often for audio, we used uncompressed raw data stream, just sound with certain parameters (11025 Hz / 22050 Hz as the most frequently used, 8-16 bits, mono / stereo, Intel / Motorola ) which was sent directly to the sound card.

Opening in hex saw the following:
image
The beginning of the file - 4 bytes contain the number 20 (00 00 00 14h). There are 20 tracks in the game. Then the next 20 groups of 4 bytes are the beginnings of the melodies. The last 4 bytes (33 A5 4B 01 = 01 4B A5 33h) are equal to the size of the music.dat file, the size of each track is equal to the difference between the two offsets. Everything turned out nice and easy.

The offset table is easy to determine - it can be incrementing digits, but sometimes the file table contains non-consecutive offsets (for example, the table of fonts of the game I have no mouth and I must scream). The offset number ranges from 0 to file size. In this case, the table goes to increase.

In the header of each track, track names are traced by a fixed offset of +16: Maintune, Technoish, Terrible, Requiem, Track 0, Lazy reggae, U97: Scramble, Gone, Rainman, Guitar song, Cool Jazz, Fir plates plant, REGRET.
Experiments with pieces in the program Game Audio Player (GAP) showed that the music is played with the following parameters - 22 kHz, 8 bit, mono, unsigned. Moreover, if you set 11kHz, the music will still play, but 2 times slower. Mono / stereo also changes the playback tempo.

Inspired by the result, I started listening to all the files of the game ... I listened to them for three days. The sound is very similar to downloading games from tapes on the Spectrum or the noise of an analog modem. I found out that the sounds in the game are reproduced as 11kHz, 8 bits, mono. I also found out that all the sounds in the game, the sound in the video sequences, the music are raw, raw data with pointers.
The title of each track is 68 bytes, it needs to be discarded, otherwise a click in front of the music is obtained.
The result was a music.dat parser-parser.
The resulting files can be heard in GAP and converted to any format.
Quest to extract the original music was completed.

Graphics


With graphics everything was a bit more confusing. Some images turned out to be RLE-compressed, some are not compressed, a part of the file header has image resolution, and the sequence can be caught as X, Y or Y, X. Some images did not contain any titles and were 32x32 pixels in size.

Content pseudo-archive and RLE compression:
image

At first there is a header - these are groups of four bytes, where the offsets to the beginning of the data block are indicated.
The last numbers 67 A9 07 00 are equal to the file length, the number of the end of the first block.
Then comes the second block of data, specifically for the file adddata.adw - this is a “insert disk” image for a normal campaign and burnt snow.
(number of files) and 4 offsets
04 00 00 00 - 10 00 00 00 - C3 A3 01 00 - C3 A6 01 00 - 52 40 03 00 - 8002 E001
The last numbers 0280h and 01E0h are the numbers 640 and 480, that is, the resolution. Numbers define a loop for the decoding procedure of a block with RLE compression.
Decoding algorithm:
A number less than or equal to 7Fh (127) specifies the number of repetitions of the next byte in the example above — this is 7Fh (127), repeat zero.
If the first number is more than 80h, then the following (X-80h) bytes are just bytes that need to be copied to a new place.
The sequence 82h 01 02 means that these are the numbers 01 and 02 without any compression.
If in place of the number of repetitions gets zero, skip.
As for the fate of the number 80h, I did not understand, it should not occur, because a difference of 80 and 80 will give zero).

In theory, we need 2 blocks - the image itself and the palette.
The beginning of block 2 is taken as zero and all further displacements point from zero. That is, if you look in the hex editor, then you need to add the initial 24 bytes, plus 4 bytes (04 00 00 00). Total +28 bytes or + 1Ch

04 00 00 00 - 4 files.
10 00 00 00 + 1Ch which indicates the beginning of the image block 8002 (640), E001 (480), that is, we set the decoding cycle, not longer than 640 Ă— 480
C3 A3 01 00 + 1Ch indicates a 256 RGB color palette, 768 bytes. Read more here .
C3 A6 01 00 + 1Ch points to the images, again 640x480
52 40 03 00 + 1Ch indicates the palette

The case remains for small, to disassemble files into blocks, unpack the compressed sections and glue with a palette.
Decoded compressed image:
image

Game sprites:
image

Images taken out of resources turned out to be dark, you need to make a bit shift to the left by 2 on each channel R, G, B.
r = r shl 2; (well, or multiply by 4, who likes)
g = g shl2;
b = b shl 2;

Some pictures for relaxation. Original, without filters, tru.
These pictures are drawn on the right of the panel when you select a unit.
image

Video


From the video, the next file came out, there are also raw data streams, pictures (questionable in what format), mixed with sound. He took out the first video from movie.adw at 1.64MB, stuck it in GAP (22kHz, 8bit, mono, unsigned) - noise, sounds, noise, sounds go together, where noise is a stream of pictures in 320x200x256 and sound in raw.
I suppose that if you rummage around the file attentively, the sound should be separated by some offsets. The video begins with the letters DLM, it is easy to find, plus if you check the starting offset table in movie.adw, they will point to DLM.

Video:
- Header 4 bytes - "DLM" + 00
- Video size + sound - 4 bytes (It coincides with a torn videoku)
- Unclear 4 bytes (type, E3 00 00 00 = 227, the number of offsets)
- Horizontal size, 4 bytes, 40 01 00 00 = 320
- Vertical size, 4 bytes, C8 00 00 00 = 200
- Some separator in 4 bytes = 04 00 00 00
- then 227 file byte offsets of 4 bytes
- Then again separator 04 00 00 00
- And it seems to end the data stream

And on this with all the video.

Little map editor


Picked the file CD: \ DATA \ MISSIONS \ 73 \ UNITS.DAT, found out the following
[DEUTCHE]
[TIGER]
6,80,3,50,100,0,142

Information about units on the map:
- The first two numbers separated by commas are the X and Y coordinates of the unit, zero begins in the upper left corner. The maximum is 128, the size of the card is 128x128, seemingly fixed; integer, 0-128
- The third number is the sprite of the unit turning, in 8 directions should be + the turn of the tower is also animated; integer 0-7. The tower is turned in the direction of the unit view.
- The fourth number - the number of life of a unit, an integer of 0-100, it looks like a percentage of the maximum of each unit;
- The fifth number - the amount of ammunition, it seems as a percentage of the maximum. 0-100.
- The last two did not understand what the numbers, changed to 1, 142 and 2, 12, in a unit, nothing has changed. Not attack / defense, checked. (the sixth, the penultimate - in enemy units indicates visibility, 0 - not visible to the player, 1 - see)
- The last seventh number is xs. It seems somehow connected with patrols, from the beginning of the game, enemy tanks drive in different ways. It looks like a behavior script, by number. From 0 to xs 255

For houses, the parameters are as follows:
[DOMES]
29,33,70,100,1

1) Building type, values ​​from 0 to 35.
2,3) The X, Y coordinates of the upper left building start are drawn to the right and down. Values ​​from approximately 1 to 128.
4) The number of "lives" of the building, in%. 0-100. Tried and 1000%, then the building can be destroyed with 6 dynamites, instead of 2 for the usual large.
5) The condition is whether to destroy the building to win the mission. 1 - an ordinary building, for the destruction there are no bonuses, 2 - the building must be destroyed to win the mission.

description of units from units.dat
[RUSSIAN] - Russian unit description branch, section
[RBTANK] - Soviet T34, medium tank, image
[RLTANK] - Light tank, T26, image
[RGUN] - Russian cannon against infantry and tanks, image
[RTROOP] - Russian infantry, image
[RSAMO] - Russian PT, type su100
[IS] - heavy Russian tank IS
[BAT] - quick-fire uncontrolled gun, image
[RGAUB] - Russian controlled howitzer,
[KATYA] - Katyusha,
[RBTR] - machine gun btr, small machine,
[RFURG] - infantry truck,
[TOWER] - tower with a machine gun,
[RZENIT] - Russian anti-aircraft gun against aircraft,
[CAR] - car with vip persona,
[RMZ] - Russian mobile anti-aircraft gun with aircraft

[DEUTCHE] - German unit description branch, section
[DGUN] - German cannon,
[DLTANK] - German light tank,
[DBTANK] - German medium tank,
[TIGER] - Tiger,
[DBIKE] - motorcycle,
[DTROOP] - infantry,
[RFURG] - van-truck, Russian, you can capture or use as your own.
[DBTR] - machine gun btr-machine
[DSAMO] - German Fri, such as Ferdinand
[DGAUB] - German controlled howitzer
[ART] - High-speed, accurate gun that can be controlled. image
[DZENIT] - Anti-aircraft guns against aircraft, image
[DMZ] - Mobile anti-aircraft gun against aircraft, image
[STIG] - German Uber-tank with a powerful gun and weak armor, Sturmtigr, image

And, for example, if you play for the Germans, you put a branch of descriptions of Isov under your description, under [DEUTCHE], then all the ISs are under your control.

As a result, he sketched a miniature - Friendship of Peoples
image

And crazy video:


But in the end, the editor didn’t finish it, because the format of the maps was not fully understood.

Subject on the forum old-games , suddenly someone will help finish the unfinished. The source code is available, unfortunately, on Delphi7.

Passage playlists:
- Campaign for the USSR ,
- Campaign for Germany ,
- Additional missions - scorched snow .

Source: https://habr.com/ru/post/186990/


All Articles