We just moved to a different server. Please be patient until all files and pages are restored and the MediaWiki software has been updated. Thank you

The Fourth Generation

From REWiki
Jump to: navigation, search

The Fourth Generation (4gen) is a small side scroller for DOS from 1996. The only common file types used in this game are FLIC and AMF. Everything else is proprietary.

Contents

.DCF

These are uncompressed archive files. The game uses basically just one DCF in which all the game data is stored. It contains no file names, so the game usually references to the "files" via indexes. DCF stands for "D'India software Chunk File" as seen in the file itself. This string is not part of the file format but is an actual chunk of 27 bytes length, found at the very first offset. There are no lengths saved with each chunk. Instead, the length of a chunk is calculated from the offset differences. DCF has the following structure:

word		num_files
dword[]		offsets
byte[]		data

Offsets are absolute, meaning the first offset is 2 + num_files * 4 instead of 0. Because num_files is 16 bits, there's a maximum of 65536 chunks possible to store inside a DCF. Internally, the games uses different offset bases for different "groupings". For example, sprite offset # 0 is actually DCF offset # 175.

Bitmaps

Bitmaps are stored in a proprietary format, the header is 8 bytes. It can contain an optional palette as well as an optional collision shape used for enemies, weapons, obstacles etc. It has the following structure:

byte		zero
byte		pal_len
word		width
word		height
byte		blend_mode
byte		coll_data_incl
byte[]		coll_data	//optional
byte[][3]	palette		//optional
byte[]		data

The first byte is always zero. pal_length is the number of color triples used for the local palette. Width and height are the bitmap dimensions in pixels. The blend_mode is used to combine the bitmap with the background in different ways (see below). When coll_data_incl is set to 1 the collision shape follows directly after the header. Its vertical dimension is equal to height but the horizontal dimension is width / 8, always rounded UP to ensure that objects smaller than 8 pixels still have one pixel of collision data. Then follows the local palette, which is 3 * pal_length bytes long. NOTE: The first index of this palette is 1 and not 0. Index 0 is used as background (or transparent) color and is not affected by this palette.

blend_mode can be one of the following:

  • 1 = completely opaque
  • 2 = pal index 0 is transparent
  • 4 = semi transparent, colors are blended additively instead of linear
  • 5 = refraction (no coloring takes place)
  • 6 = heightmap

At the moment, I have no idea how the local palette is mapped to the global palette. The game runs in 8 bit graphics mode of course (256 colors), so the bitmaps can't use their local palette without some kind of index remapping!

Scenes

The definitions for the different background scenes are arranged in one chunk. Each scene has a length of 4262 bytes, containing layer properties and object placement:

byte		name_len
char[19]	name
byte		?
byte		?
byte		water_fx
word[3]		color_correction
SC_LAYER[6]	layers

name_len is the length of the scene's name, but the actual name field has a fixed size of 19 bytes. When water_fx is set to 1, the whole screen is distorted with a sine-wave animation – only used in the underwater scene. All colors of the global palette are multiplied by the color_correction vector. The last field consists of 6 layers which contain information about the images used and how to display them. The SC_LAYER struct contains the following:

byte		enabled
word		?		// always 0
smallint	y_pos		// or FOV in 3D mode
word		scroll_speed
word		type
word		eye_height	// 3D only
word		y_clipping	// 3D only
word		?		// always 0
word[200]	images
word		num_img
SC_OBJ[18]	objects 

Only when enabled is set o 1, the layer becomes visible. y_pos has two different meanings: for normal (flat) images it means the vertical position of the image in screen pixels. But when 3D mode is used, this parameter is the field of view of the texture. scroll_speed defines how fast the layer scrolls to the left:

  • 1 = 4 px/frame
  • 2 = 2 px/frame
  • 3 = 1 px/frame
  • 4 = 2 frames/px
  • etc.

The type field defines the appearance of the layer:

  • 0 = flat
  • 1 = ground (3D)
  • 2 = clouds (3D)
  • 4 = heightmap (3D)

The eye_height parameter defines how far away the texture is from the "camera" in Y direction. y_clipping is the vertical screen position (in pixels) at which the texture plane is clipped. It is automatically measured from top (clouds, type = 2) or bottom (ground, type = 1). The images array contains the indexes for the images that make up the layer. The image sequence of every layer is looped infinitely. The number of images used in a layer is defined by the num_img parameter. Every background image has the same fixed horizontal dimension of 320 px. If an invalid index is given, there's still a 320 px wide gap to the next image. The last field is an array of 18 optional backdrop objects, which support animations and can be placed at arbitrary positions (This feature is actually only used for the space scene, with the rotating space station at the beginning). The SC_OBJ struct contains the following:

word		offset
word		x
word		y
word		image_idx
word		frames
word		?
word		?
word		frame_rate

offset specifies the "slot" at which the object is placed. A "slot" has a fixed width of 320 px, meaning the value of this parameter is actually multiplied by 320. The position of the image relative to the slot is given by the x and y parameters. The image_idx is the first frame of the animation, or the only frame, depending on the frames parameter. If this is >0 then the subsequent indexes after the image_idx is used for the animation frames. That means that the images must be arranged accordingly inside the .DCF file! And finally, the frame_rate defines the speed of the animation.

Objects

All objects are defined in one chunk. One object definition is 68 bytes long:

byte		name_len
char[19]	name
word		logic
smallint	velocity
word		img_down
word		img_up
word		img_level
word		frames
word		frame_rate
word		wpn1
word		wpn2
word		health	
word		collision_dmg		
word		?	// always 2		
word		explosion
word		turn_dist
word		?
word		?
word		?
word		?
byte		?
byte		powerup
word		muzzle_x
word		muzzle_y
word		nozzle_x
word		nozzle_y
word		?

The logic is the behavior of the object. velocity is the movement speed, which can also be negative, if an enemy comes from behind (left screen side). img_down, img_up and img_level are the images used for the 3 states of vertical movement (up, down, or not at all). This does not apply to every logic. The frames parameter is the number of subsequent frames used for the animation (if > 0). The first frame is img_level in most cases. The enemy's primary and secondary weapon number is defined in the wpn1 and wpn2 fields respectively. health – no comment. collision_dmg is the amount of damage inflicted to the player when he collides with the object. The exploson parameter specifies the type of explosion after an object is destroyed. It affects the size and the number of explosion sprites as well as the number of debris pieces and the appearance of the white shockwave-like circle for bigger explosions. If an object can change its direction on the x-axis, the turn_dist parameter is the position in screen pixels at which the object starts to change its course. Does only apply to a handful of logics. If the powerup byte is set to 20, an energy cell is left behind after the object is destroyed. The player can pick up the cell to slightly increase the shield's strength. The two muzzle parameters are the x and y positions (in pixels) from the top left corner of the object's image at which the projectiles are fired. The same goes for the nozzle parameter, which specifies the x and y position of the jet engine.

Weapons

Every definition block has a length of 55 bytes:

byte		name_len
char[19]	name
smallint	velocity
word		rot_speed
word		image_idx
word		frames
word		frame_rate
word		logic
word		damage
word		impact_type	
word		interval1
word		interval2
word		energy
word		? 		// always 2
word		?
word		?
smallint	vel_vertical
word		?
byte		?		// always 0
word		?		// always 65535

velocity is the forward speed of the projectile. rot_speed defines how fast the projectile changes the direction to follow the target (only used for missiles and the "stalker" weapon). As always, image_idx is the .DCF index of the image to use and frames is the number of animation frames, which are played back at the rate defined in frame_rate. NOTE: some weapons use the frame parameter actually not as animation but as different images for different moving directions! logic is the actual weapon type. The number of projectiles per shot, the movement pattern and the ability to seek a target are influenced by this value. The value of damage is inflicted to the target and impact_type is the explosion animation of the projectile. interval1 is the number of frames between each shot, interval2 is the number of frames between a burst of shots. The value of the energy parameter reflects the energy consumption per shot. Some weapons fire 3 projectiles at once that are traveling not just straight ahead but also up and down as specified with the vel_vertical parameter.

Levels

Every level file (chunk) is 20597 bytes long:

word[2000]	remapping
byte[200]	availability
word		scene
word		music
word		gravity
byte		upgrade
word		flic
word		?
word		?
word		?
word[8191]	events

It consists of 4 sections. The first one is an array of words where each one is an index which refers to a bitmap that is either processed or ignored during loading. If the value of an index is 65535 the bitmap is ignored. If the value is between 0 and 3, the bitmap's palette is mapped to the global palette in different ways. NOTE: I have not yet discovered how the actual processing works. In my tests, the visual differences are minimal but to me it seems as if the value specifies different quantization algorithms to drop a few colors of a bitmap's palette in favor for other bitmaps to gain a bit of quality. But until I know more, this has to be considered wild speculation! The fixed length of that array becomes a problem if someone would want to mod the game and add more content to it (instead of overwriting existing chunks) because even if the DCF archive can hold up to 65536 files, the above mentioned array can only manage 2000 images without manipulating the game executable directly.

Then follows an array of 200 bytes to make certain items available for the player to upgrade the ship with. Only weapons are affected by this, all other items are always available. The following list shows which byte # makes which item available by setting its value to 1.

Standard weapons:

  • 117 = Twin Cannons (unused)
  • 118 = Pulse Cannons
  • 119 = Velden arrow
  • 120 = Blue Daggers
  • 121 = Tempest
  • 122 = Sonic Wave
  • 123 = Helix
  • 124 = Laser
  • 125 = Stalker

Special weapons:

  • 126 = Photon Pulse
  • 127 = Scorpion Missile
  • 128 = Rage Missile
  • 129 = X-29 Missile
  • 130 = Flux Beam
  • 131 = Disintegrator (unused)

The next 15 bytes contain some information about the level: scene is the index of the background scene and music is the index of the AMF file to play. The gravity parameter has only an effect on debris pieces. If it's 0 there's no gravity and the pieces drift away with their initial speed. If this value is 1 then gravity is applied to them. Before each level, the player has the ability to upgrade the ship, but only if this parameter is set to 1. The flic parameter is the number of the FLIC file to be used as background animation for the upgrade screen. 6 being the hangar animation and 7 the space flight animation. The game crashes when an invalid number is given.

The last section holds the list of events. An event consists of an identifier and up to 4 parameters. All parameters, including the identifier, are two bytes long. Events are executed one after another as specified in an event's delta parameter. This is the time to wait before the next event is executed. There are at least 18 event types. NOTE: I haven't tested everything in-depth yet so the following list is based pretty much on what I could make out on first sight! That means the list is far from perfect.

  • 00 01 object x y delta 

The most common event, used to spawn an object. The object parameter refers to an index inside the object definition chunk. x and y are the coordinates where the object is created and the delta parameter is the time to wait before the next event is executed. A value of 0 executes the next event immediately. Most events seem to have a delta parameter but there are too many unknowns to be really sure about it.

  • 00 02 unknown1 unknown2 unknown3 

?

  • 00 03 unknown1 unknown2 

?

  • 00 05 delta 

Suspends the processing of events for the given time.

  • 00 07 speed delta unknown1 unknown2 

Sets the scrolling speed. When speed is 0, the scrolling stops. The initial value is 4. This is always the first event in the list but it's not a requirement to be the first.

  • 00 08 unknown 

Can be found at the end of the list, just before [00 17]. The unknown parameter is always 0.

  • 00 09 unknown 

Attachment. This event attaches the object, that is spawned by the following [00 01], to the object, which was previously spawned after a [00 0A]. In this case, the coordinates of the following [00 01] are relative to the "parent" object. Objects spawned this way don't move on their own. They're attached to the parent object and move together with it.

  • 00 0A unknown 

Parenting. This event marks the following [00 01] as "parent" for further objects, which are in turn marked as "children" by a preceding [00 09].

  • 00 0B unknown delta 

?

  • 00 0C object delta 

?

  • 00 0D unknown delta 

?

  • 00 0F

The only event without parameter. It can only be found after a [00 0C] event.

  • 00 13 offset delta 

Jumps to the event specified by the offset parameter. The offset is in bytes and NOT in words and is relative to the start of the event list. 0 is the first entry. This is used to loop a section of the list while a boss fight takes place.

  • 00 14 unknown1 unknown2 unknown3 unknown4 

?

  • 00 15 unknown1 unknown2 unknown3 

?

  • 00 16 unknown1 unknown2 

?

  • 00 17 unknown 

This marks the end of the event list and thus, the end of the level. The unknown parameter is 0 most of the time. This event goes "hand in hand" with [00 08], that COULD mean that these two blocks are actually just one, where the "00 17" is just a parameter inside event type [00 08].

  • 0A 00 unknown1 unknown2 

?


The space after the list is padded with zeros until the chunk is 20597 bytes long. The gameplay takes place in screen space and NOT in world space. The player as well as every other object does actually not move through the level. Instead, the illusion of movement is only realized through the background scene. Objects are just spawned left and right of the screen, like in a shooting gallery.

Sounds

Headerless, uncompressed RAW files in 8 bit unsigned PCM format with a sample rate of 11 kHz.

.AMF

The music is in Scream Tracker 3 format, converted to AMF as required to work with DPMI, an interface which is also used by other DOS applications back in the day…

Format description

.FLIC

All the short pre-rendered cut scenes are Autodesk Animator files…

Format description

Beta / Cut / Unused content

  • Originally, it was planned to have mission introduction messages before each level. There are text files for each mission but only the first 5 are finished. The remaining 6 are just copied over from the 5th.
  • Furthermore, there was a boss planned for level 5, "a high powered super tank and its escort convoy" according to the unused text.
  • There is an unused picture of a person (very likely one of the developers) which was intended to be shown on the credits screen.
  • A handful of sprites, some of them even animated, can be found but are never used in the game.
  • And a few weapons, although fully functional, were cut from the final game.
Personal tools