From cb26bbc4915c7ac622395ebd3a2b630062ca044f Mon Sep 17 00:00:00 2001 From: chrisf Date: Sat, 23 Jun 2007 18:42:56 +0000 Subject: [PATCH] git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1066 993157c7-ee19-0410-b2c4-bb4e9862e678 --- ShpViewer/ShpViewForm.Designer.cs | 22 ++- ShpViewer/ShpViewForm.cs | 16 +-- ShpViewer/ShpViewForm.resx | 120 ++++++++++++++++ ShpViewer/ShpViewer.csproj | 4 + aud format.txt | 229 ++++++++++++++++++++++++++++++ 5 files changed, 381 insertions(+), 10 deletions(-) create mode 100644 ShpViewer/ShpViewForm.resx create mode 100644 aud format.txt diff --git a/ShpViewer/ShpViewForm.Designer.cs b/ShpViewer/ShpViewForm.Designer.cs index b7c79d6e04..bc3699d35d 100644 --- a/ShpViewer/ShpViewForm.Designer.cs +++ b/ShpViewer/ShpViewForm.Designer.cs @@ -28,12 +28,32 @@ namespace ShpViewer /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.SuspendLayout(); + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(292, 273); + this.flowLayoutPanel1.TabIndex = 0; + // + // ShpViewForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 273); + this.Controls.Add(this.flowLayoutPanel1); + this.Name = "ShpViewForm"; this.Text = "Form1"; + this.ResumeLayout(false); + } #endregion + + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; } } diff --git a/ShpViewer/ShpViewForm.cs b/ShpViewer/ShpViewForm.cs index 7d0f9e37e5..4dd8a8bd22 100644 --- a/ShpViewer/ShpViewForm.cs +++ b/ShpViewer/ShpViewForm.cs @@ -34,18 +34,16 @@ namespace ShpViewer } InitializeComponent(); - } - protected override void OnPaint( PaintEventArgs e ) - { - base.OnPaint( e ); - - int y = 10; - foreach( Bitmap b in bitmaps ) + foreach (Bitmap b in bitmaps) { - e.Graphics.DrawImage( b, 10, y ); - y += 10 + b.Height; + PictureBox p = new PictureBox(); + p.Image = b; + p.Size = b.Size; + flowLayoutPanel1.Controls.Add(p); } + + Focus(); } } } \ No newline at end of file diff --git a/ShpViewer/ShpViewForm.resx b/ShpViewer/ShpViewForm.resx new file mode 100644 index 0000000000..ff31a6db56 --- /dev/null +++ b/ShpViewer/ShpViewForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ShpViewer/ShpViewer.csproj b/ShpViewer/ShpViewer.csproj index a28e9d3bce..811873aa2c 100644 --- a/ShpViewer/ShpViewer.csproj +++ b/ShpViewer/ShpViewer.csproj @@ -51,6 +51,10 @@ Resources.Designer.cs Designer + + Designer + ShpViewForm.cs + True Resources.resx diff --git a/aud format.txt b/aud format.txt new file mode 100644 index 0000000000..c2b3890e42 --- /dev/null +++ b/aud format.txt @@ -0,0 +1,229 @@ + + THE AUD FILE FORMAT + +Revision 3 + +by Vladan Bato (bat22@geocities.com) + + +In this document I'll try to describe the AUD file format used in +Command & Conquer and Redalert. + +Command & Conquer is a trademark of Westwood Studios, Inc. +Command & Conquer is Copyright (C)1995 Westwood Studios, Inc. +Command & Conquer: Red Alert is a trademark of Westwood Studios, Inc. +Command & Conquer: Red Alert is Copyright (C)1995,1996 Westwood Studios, Inc. + +The information provided here is for anyone who would like to make an +AUD player program or AUD to WAV or WAV to AUD converters. + +Most information about AUD files and IMA-ADPCM compression has been +provided by Douglas McFadyen. + +I won't explain here the format of the WAV files. You'll have to find this +info yourself. I'll just tell you how to obtain 16-bit PCM data and how +to encode it. + +I will use Pascal-like notation throughout this document. + +=============================== + 0. IMPRTANT NOTE - WHAT'S NEW +=============================== + +This revision contains an important difference in the IMA-ADPCM compression +routine. Instead of computing the diffrence between the current and +previous sample, it computes the difference between the current sample +and the value that the decoding routine will predict for the previous +sample. +This is the way the algorithm is implemented in C&C. +If you implement it the way it was in previous revisions of this document, +the sound will be the same but there will be a "pop" sound at the end. + + +============== + 1. AUD FILES +============== + +The AUD files have the following header : + + Header : record + SamplesPerSec : word; {Frequency} + Size : longint; {Size of file (without header)} + OutSize : longint; {Size of ouput data} + Flags : byte; {bit 0=stereo, bit 1=16bit} + Typ : byte; {1=WW compressed, 99=IMA ADPCM} + end; + +There are two types of compression. The first is the IMA-ADPCM compression +used for 16-bit sound. It's used in most AUD files. + +The other one is a Westwood's proprietary compression for 8-bit sound and +is used only for death screams. I won't describe it in this document +because I don't know how it works. + +The rest of the AUD files is divided in chunks. These are usually 512 +bytes long, except for the last one. + +Each chunk has the following header : + + ChunkHd : record + Size : word; {Size of compressed data} + OutSize : word; {Size of ouput data} + ID : longint; {Always $0000DEAF} + end; + +The IMA-ADPCM compression compresses 16-bit samples to 4 bits. This means +that OutSize will be apporximately 4*Size. + +The IMA-ADPCM compression and decompression are described in the following +sections. + +Note that the current sample value and index into the Step Table should +be initialized to 0 at the start and are mantained across the chunks +(see below). + +========================== + 2. IMA-ADPCM COMPRESSION +========================== + +I won't describe the theory behind the IMA-ADPCM compression. I will just +give some pseudo code to compress and decompress data. + +The compression algorithm takes a stream of signed 16-bit samples in input +and produces a stream of 4-bit codes in output. +The 4-bit codes are stored in pairs (two codes in one byte). The first one +is stored in the lower four bits. + +Two varaibles must be mantained while compressing : the previous sample +value and the current index into the step table. + +You can find the Step Table in Appendix B. +The Index adjustment table is in Appendix A. + +Here's the pseudo-code that will do the compression : + + Index:=0; + Prev_Sample:=0; + + while there_is_more_data do + begin + Cur_Sample:=Get_Next_Sample; + Delta:=Cur_Sample-Prev_Sample; + if Delta<0 then + begin + Delta:=-Delta; + Sb:=1; + end else Sb:=0; + {Sb is bit 4 of the output Code (sign bit)} + + Code := 4*Delta div Step_Table[Index]; + if Code>7 then Code:=7; + {These are the 3 low-order bits of output code} + + Index:=Index+Index_Adjust[Code]; + if Index<0 then Index:=0; + if Index>88 the Index:=88; + + Predicted_Delta:=(Step_Table[Index]*Code) div 4 + + Step_Table[Index] div 8; + + {This is the Delta that decoding routine will compute} + + Prev_Sample:=Prev_Sample+Predicted_Delta; + if Prev_Sample>32767 then Prev_Sample:=32767 + else if Prev_Sample<-32768 then Prev_Sample:=-32768; + + {Prev_Sample is the sample value that the decoding routine + will compute} + + + Output_Code(Code+Sb*8); + end; + +Note that this code is usually implemented in more efficient manner +(No need to divide). + +The Get_Next_Sample function should return the next sample from the input +buffer. +The Output_Code function should store the 4-bit code to the output buffer. +One byte contains two 4-bit codes, and this function should take care of +this. + +============================ + 3. IMA-ADPCM DECOMPRESSION +============================ + +It is the exact opposite of the above. It receives 4-bit codes in input +and produce 16-bit samples in output. + +Again you have to mantain an Index into the Step Table an the current +sample value. + +The tables used are the same as for compression. + +Here's the code : + + Index:=0; + Cur_Sample:=0; + + while there_is_more_data do + begin + Code:=Get_Next_Code; + + if (Code and $8) <> 0 then Sb:=1 else Sb:=0; + Code:=Code and $7; + {Separate the sign bit from the rest} + + Delta:=(Step_Table[Index]*Code) div 4 + Step_Table[Index] div 8; + {The last one is to minimize errors} + + if Sb=1 then Delta:=-Delta; + + Cur_Sample:=Cur_Sample+Delta; + if Cur_Sample>32767 then Cur_Sample:=32767 + else if Cur_Sample<-32768 then Cur_Sample:=-32768; + + Output_Sample(Cur_Sample); + + Index:=Index+Index_Adjust[Code]; + if Index<0 then Index:=0; + if Index>88 the Index:=88; + end; + +Again, this can be done more efficiently (no need for multiplication). + +The Get_Next_Code function should return the next 4-bit code. It must +extract it from the input buffer (note that two 4-bit codes are stored +in the same byte, the first one in the lower bits). + +The Output_Sample function should write the signed 16-bit sample to the +output buffer. + +========================================= + Appendix A : THE INDEX ADJUSTMENT TABLE +========================================= + + Index_Adjust : array [0..7] of integer = (-1,-1,-1,-1,2,4,6,8); + +============================= + Appendix B : THE STEP TABLE +============================= + + Steps_Table : array [0..88] of integer =( + 7, 8, 9, 10, 11, 12, 13, 14, 16, + 17, 19, 21, 23, 25, 28, 31, 34, 37, + 41, 45, 50, 55, 60, 66, 73, 80, 88, + 97, 107, 118, 130, 143, 157, 173, 190, 209, + 230, 253, 279, 307, 337, 371, 408, 449, 494, + 544, 598, 658, 724, 796, 876, 963, 1060, 1166, + 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, + 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, + 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 ); + + +--- + +Vladan Bato (bat22@geocities.com) +http://www.geocities.com/SiliconValley/8682 +