예제 #1
0
파일: Program.cs 프로젝트: XAYRGA/bstParser
        public static BSTWaveInfo readStream(BeBinaryReader br, int fmt)
        {
            var newWI = new BSTWaveInfo();

            newWI.format = fmt;
            switch (fmt & 0xF0)
            {
            case 0x40:
                break;

            case 0x50:
                // Console.WriteLine($"{br.BaseStream.Position:X}");
                newWI.wSoundID = br.ReadInt16();
                // Console.WriteLine(newWI.wSoundID);
                break;

            case 0x60:
                break;

            case 0x70:
                newWI.streamFormat = br.ReadByte();
                newWI.unk1         = br.ReadByte();
                newWI.flags        = br.ReadUInt16();
                var namePointer = br.ReadInt32();
                br.BaseStream.Position = namePointer;
                newWI.streamFilePath   = JBST.readTerminated(br, 0x00);
                break;
            }
            return(newWI);
        }
예제 #2
0
        private void BtnLoadCHA_Click(object sender, win.RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "Photoshop RGB Channel Mixer Preset (.cha)|*.cha";

            float[,] PSmatrix = new float[3, 3];
            int[] useless  = new int[3]; // I think these are for CMYK
            int[] constant = new int[3];

            if (ofd.ShowDialog() == true)
            {
                string filename = ofd.FileName;
                using (FileStream fs = File.Open(filename, FileMode.Open))
                {
                    using (BeBinaryReader binReader = new BeBinaryReader(fs))
                    {
                        uint version    = binReader.ReadUInt16();
                        uint monochrome = binReader.ReadUInt16();
                        PSmatrix[0, 0] = binReader.ReadInt16() / 100f;
                        PSmatrix[0, 1] = binReader.ReadInt16() / 100f;
                        PSmatrix[0, 2] = binReader.ReadInt16() / 100f;
                        useless[0]     = binReader.ReadInt16();
                        constant[0]    = binReader.ReadInt16();
                        PSmatrix[1, 0] = binReader.ReadInt16() / 100f;
                        PSmatrix[1, 1] = binReader.ReadInt16() / 100f;
                        PSmatrix[1, 2] = binReader.ReadInt16() / 100f;
                        useless[1]     = binReader.ReadInt16();
                        constant[1]    = binReader.ReadInt16();
                        PSmatrix[2, 0] = binReader.ReadInt16() / 100f;
                        PSmatrix[2, 1] = binReader.ReadInt16() / 100f;
                        PSmatrix[2, 2] = binReader.ReadInt16() / 100f;
                        useless[2]     = binReader.ReadInt16();
                        constant[2]    = binReader.ReadInt16();
                    }
                }

                setStatus(Helpers.matrixToString <float>(PSmatrix));
                SetSlidersToMatrix(PSmatrix);
                RegradeImage(PSmatrix);
            }
        }
예제 #3
0
        public static InstructionSet Disassemble(string path)
        {
            InstructionSet instructionSet = new InstructionSet();

            using (var file = File.Open(path, FileMode.Open)) {
                using (var reader = new BeBinaryReader(file)) {
                    while (reader.BaseStream.Position != reader.BaseStream.Length)
                    {
                        byte operation       = reader.ReadByte();
                        var  parameterSchema = parameterSchemas[operation];
                        var  parameters      = new List <TypedNumber>();
                        for (var i = 0; i < parameterSchema.Length; i++)
                        {
                            var parameter = parameterSchema[i];
                            switch (parameter)
                            {
                            case ParameterType.size_8:
                                parameters.Add(TypedNumber.TypedByte(
                                                   reader.ReadByte()
                                                   ));
                                break;

                            case ParameterType.size_16:
                                parameters.Add(TypedNumber.TypedShort(
                                                   reader.ReadUInt16()
                                                   ));
                                break;

                            case ParameterType.size_32:
                                parameters.Add(TypedNumber.TypedInt(
                                                   reader.ReadUInt32()
                                                   ));
                                break;
                            }
                        }
                        instructionSet.Add(new Instruction(
                                               opcode: operation,
                                               parameters: parameters.ToArray()
                                               ));
                    }
                }
            }
            return(instructionSet);
        }
예제 #4
0
파일: Program.cs 프로젝트: XAYRGA/bstParser
        private static byte[] readUntilSequenceEnd(BeBinaryReader br)
        {
            var len        = 0;
            int SEQ_OPCODE = 0xFF00FF;
            var anchor     = br.BaseStream.Position;

            try
            {
                while ((SEQ_OPCODE = br.ReadUInt16()) != 0xFFC1 && SEQ_OPCODE != 0xFFC3) // f**k so hard.
                {
                    br.BaseStream.Position -= 1;                                         // f**k alignment, seek back one byte then read the next short in the buffer lol.
                    len++;
                }
            } catch (Exception E) { Console.WriteLine($"Terminated loop... {E.Message}"); }
            br.BaseStream.Position = anchor;
            len += 1;
            byte[] ret = new byte[len];
            br.BaseStream.Read(ret, 0, len);
            return(ret);
        }
예제 #5
0
        private void loadIBNKJaiV1(BeBinaryReader instReader)
        {
            long anchor         = 0;
            var  BaseAddress    = instReader.BaseStream.Position;
            var  current_header = 0u;

            current_header = instReader.ReadUInt32(); // read the first 4 byteas
            if (current_header != 0x49424e4b)         // Check to see if it equals IBNK
            {
                throw new InvalidDataException("Scanned header is not an IBNK.");
            }
            var size = instReader.ReadUInt32();

            id = instReader.ReadInt32();                          // Global virtual ID
            instReader.BaseStream.Seek(0x14, SeekOrigin.Current); // 0x14 bytes always blank
            current_header = instReader.ReadUInt32();             // We should be reading "BANK"
            for (int inst_id = 0; inst_id < 0xF0; inst_id++)
            {
                var inst_offset = instReader.ReadInt32();                       // Read the relative pointer to the instrument
                anchor = instReader.BaseStream.Position;                        // store the position to jump back into.
                if (inst_offset > 0)                                            // If we have a 0 offset, then the instrument is unassigned.
                {
                    instReader.BaseStream.Position = BaseAddress + inst_offset; // Seek to the offset of the instrument.
                    current_header = instReader.ReadUInt32();                   // Read the 4 byte identity of the instrument.
                    var NewINST = new Instrument();
                    NewINST.Keys = new InstrumentKey[0xF0];
                    switch (current_header)
                    {
                    case INST:
                    {
                        instReader.ReadUInt32();                  // The first 4 bytes following an instrument is always 0, for some reason.  Maybe reserved.
                        NewINST.Pitch  = instReader.ReadSingle(); // 4 byte float pitch
                        NewINST.Volume = instReader.ReadSingle(); // 4 byte float volume
                        /* Lots of skipping, i havent added these yet, but i'll comment what they are. */
                        var poscioffs = instReader.ReadUInt32();  // offset to first oscillator table
                        var poscicnt  = instReader.ReadUInt32();  // Offset to second oscillator count
                        // Console.WriteLine("Oscillator at 0x{0:X}, length {1}", poscioffs, poscicnt);
                        //Console.ReadLine();
                        instReader.ReadUInt32();                // Offset to first effect object
                        instReader.ReadUInt32();                // offset to second effect object
                        instReader.ReadUInt32();                // offset of first sensor object
                        instReader.ReadUInt32();                // offset of second sensor object
                        /*////////////////////////////////////////////////////////////////////////////*/
                        var keyCounts = instReader.ReadInt32(); // How many key regions are in here.
                        int KeyHigh   = 0;
                        int KeyLow    = 0;
                        for (int k = 0; k < keyCounts; k++)
                        {
                            var NewKey = new InstrumentKey();
                            NewKey.keys = new InstrumentKeyVelocity[0x81];
                            var keyreg_offset = instReader.ReadInt32();                   // This will be where the data for our key region is.
                            var keyptr_return = instReader.BaseStream.Position;           // This is our position after reading the pointer, we'll need to return to it
                            instReader.BaseStream.Position = BaseAddress + keyreg_offset; // Seek to the key region
                            byte key = instReader.ReadByte();                             // Read the key identifierr
                            KeyHigh = key;                                                // Set the highest key to what we just read.
                            instReader.BaseStream.Seek(3, SeekOrigin.Current);            // 3 bytes, unused.
                            var VelocityRegionCount = instReader.ReadInt32();             // read the number of entries in the velocity region array
                            for (int b = 0; b < VelocityRegionCount; b++)
                            {
                                var NewVelR     = new InstrumentKeyVelocity();
                                var velreg_offs = instReader.ReadInt32();         // read the offset of the velocity region
                                var velreg_retn = instReader.BaseStream.Position; // another one of these.  Return pointer
                                instReader.BaseStream.Position = velreg_offs + BaseAddress;
                                int VelLow  = 0;
                                int VelHigh = 0;
                                {
                                    var velocity = instReader.ReadByte();                    // The velocity of this key.
                                    VelHigh = velocity;
                                    instReader.BaseStream.Seek(3, SeekOrigin.Current);       // Unused.
                                    NewVelR.velocity = velocity;
                                    NewVelR.wsysid   = instReader.ReadUInt16();              // This will be the ID of the WAVESYSTEM that its in
                                    NewVelR.wave     = instReader.ReadUInt16();              // This will be the ID of the wave inside of that wavesystem
                                    NewVelR.Volume   = instReader.ReadSingle();              // Finetune, volume, float
                                    NewVelR.Pitch    = instReader.ReadSingle();              // finetune pitch, float.
                                    for (int idx = 0; idx < ((1 + VelHigh) - VelLow); idx++) // See below for what this is doing
                                    {
                                        NewKey.keys[(VelLow + idx)] = NewVelR;
                                        NewKey.keys[127]            = NewVelR;
                                    }
                                    VelLow = VelHigh;
                                }
                                instReader.BaseStream.Position = velreg_retn;  // return to our pointer position  [THIS IS BELOW]
                            }
                            for (int idx = 0; idx < (KeyHigh - KeyLow); idx++) // The keys are gappy.
                            {
                                NewINST.Keys[(KeyLow + idx)] = NewKey;         // So we want to interpolate the previous keys across the empty ones, so that way it's a region
                                NewINST.Keys[127]            = NewKey;
                            }
                            KeyLow = KeyHigh;                               // Set our new lowest key to the previous highest
                            instReader.BaseStream.Position = keyptr_return; // return to our last pointer position
                        }


                        break;
                    }

                    case PER2:
                    {
                        NewINST.IsPercussion = true;
                        instReader.BaseStream.Seek(0x84, SeekOrigin.Current);         // 0x88 - 4 (PERC)
                        for (int per = 0; per < 100; per++)
                        {
                            var NewKey = new InstrumentKey();
                            NewKey.keys = new InstrumentKeyVelocity[0x81];

                            var keyreg_offset = instReader.ReadInt32();         // This will be where the data for our key region is.
                            var keyptr_return = instReader.BaseStream.Position; // This is our position after reading the pointer, we'll need to return to it
                            if (keyreg_offset == 0)
                            {
                                continue;                                                 // Skip, its empty.
                            }
                            instReader.BaseStream.Position = BaseAddress + keyreg_offset; // seek to position.
                            NewINST.Pitch  = instReader.ReadSingle();
                            NewINST.Volume = instReader.ReadSingle();
                            instReader.BaseStream.Seek(8, SeekOrigin.Current);
                            var VelocityRegionCount = instReader.ReadInt32();         // read the number of entries in the velocity region array
                            for (int b = 0; b < VelocityRegionCount; b++)
                            {
                                var NewVelR     = new InstrumentKeyVelocity();
                                var velreg_offs = instReader.ReadInt32();         // read the offset of the velocity region
                                var velreg_retn = instReader.BaseStream.Position; // another one of these.  Return pointer
                                instReader.BaseStream.Position = velreg_offs + BaseAddress;
                                int VelLow  = 0;
                                int VelHigh = 0;
                                {
                                    var velocity = instReader.ReadByte();                // The velocity of this key.
                                    VelHigh = velocity;
                                    instReader.BaseStream.Seek(3, SeekOrigin.Current);   // Unused.
                                    NewVelR.velocity = velocity;
                                    NewVelR.wsysid   = instReader.ReadUInt16();          // This will be the ID of the WAVESYSTEM that its in

                                    NewVelR.wave   = instReader.ReadUInt16();            // This will be the ID of the wave inside of that wavesystem
                                    NewVelR.Volume = instReader.ReadSingle();            // Finetune, volume, float
                                    NewVelR.Pitch  = instReader.ReadSingle();            // finetune pitch, float.
                                    for (int idx = 0; idx < (VelHigh - (VelLow)); idx++) // See below for what this is doing
                                    {
                                        NewKey.keys[(VelLow + (idx))] = NewVelR;
                                        NewKey.keys[127] = NewVelR;
                                    }
                                    VelLow = VelHigh;
                                }
                                instReader.BaseStream.Position = velreg_retn;         // return to our pointer position  [THIS IS BELOW]
                            }
                            instReader.BaseStream.Position = keyptr_return;
                            NewINST.Keys[per] = NewKey;         // oops, add to instrument data or else it doesnt load x.x
                            NewINST.Keys[127] = NewKey;
                        }

                        break;
                    }

                    case PERC:

                        break;
                    }
                    Instruments[inst_id] = NewINST;      // Store it in the instruments bank
                }
                instReader.BaseStream.Position = anchor; // return back to our original pos to read the next pointer
            }
        }
예제 #6
0
 private void HandlePort(BeBinaryReader reader)
 {
     Debug($"Port {reader.ReadUInt16()}");
 }
예제 #7
0
        public static void Unpack(string xgr, string dir)
        {
            string imgb = Path.Combine(Path.GetDirectoryName(xgr), $"{Path.GetFileNameWithoutExtension(xgr)}.imgb");

            if (!File.Exists(imgb))
            {
                throw new Exception("IMGB file not found.");
            }
            FileStream     stream     = File.OpenRead(xgr);
            FileStream     imgbStream = File.OpenRead(imgb);
            BeBinaryReader reader     = new BeBinaryReader(stream);
            BinaryReader   imgbReader = new BinaryReader(imgbStream);

            if (reader.ReadInt32() == 0x57504400)
            {
                uint fileCount = reader.ReadUInt32();
                reader.BaseStream.Position += 8; //zeroes
                for (int i = 0; i < fileCount; i++)
                {
                    string fileName   = Encoding.ASCII.GetString(reader.ReadBytes(16)).Replace($"{(char)0}", string.Empty);
                    uint   infoOffset = reader.ReadUInt32();
                    uint   infoSize   = reader.ReadUInt32();
                    string fileExt    = Encoding.ASCII.GetString(reader.ReadBytes(8)).Replace($"{(char)0}", string.Empty);
                    string filePath   = Path.Combine(dir, $"{fileName}.{fileExt}");
                    long   current    = reader.BaseStream.Position;
                    reader.BaseStream.Position = infoOffset;
                    if (fileExt == "txbh")
                    {
                        string magicWord = Encoding.ASCII.GetString(reader.ReadBytes(8)).Replace($"{(char)0}", string.Empty);
                        reader.BaseStream.Position += 56; //unknow
                        string fileType = Encoding.ASCII.GetString(reader.ReadBytes(4)).Replace($"{(char)0}", string.Empty);
                        reader.BaseStream.Position += 2;  //unknow
                        GTEXFormat.GtexPixelFormat format = (GTEXFormat.GtexPixelFormat)reader.ReadByte();
                        byte mimapCount = reader.ReadByte();
                        reader.ReadByte(); //unknow
                        bool   isCubeMap = reader.ReadBoolean();
                        ushort width     = reader.ReadUInt16();
                        ushort height    = reader.ReadUInt16();
                        short  depth     = reader.ReadInt16();
                        int    linerSize = reader.ReadInt32();
                        reader.BaseStream.Position += 4;
                        uint offsetImgb = reader.ReadUInt32();
                        uint size       = reader.ReadUInt32();
                        imgbReader.BaseStream.Position = offsetImgb;
                        byte[] raw    = imgbReader.ReadBytes((int)size);
                        byte[] result = DDS.Create(width, height, format, mimapCount, depth, linerSize, raw);
                        File.WriteAllBytes($"{filePath}.dds", result);
                    }
                    else
                    {
                        byte[] bytes = reader.ReadBytes((int)infoSize);
                        File.WriteAllBytes($"{filePath}.{fileExt}", bytes);
                    }
                    Console.WriteLine($"Unpacked: {fileName}.{fileExt}");
                    reader.BaseStream.Position = current;
                }
            }
            else
            {
                throw new Exception("File is not a XGR file.");
            }
            reader.Close();
            stream.Close();
            imgbReader.Close();
            imgbStream.Close();
        }
예제 #8
0
 public static OfpPort Parse(this BeBinaryReader br, out OfpPort b)
 {
     b = (OfpPort)br.ReadUInt16();
     return(b);
 }
예제 #9
0
 public static OfpErrorType Parse(this BeBinaryReader br, out OfpErrorType b)
 {
     b = (OfpErrorType)br.ReadUInt16();
     return(b);
 }
예제 #10
0
 public static OfpStatsFlagsReply Parse(this BeBinaryReader br, out OfpStatsFlagsReply b)
 {
     b = (OfpStatsFlagsReply)br.ReadUInt16();
     return(b);
 }
예제 #11
0
 public static OfpStatsTypes Parse(this BeBinaryReader br, out OfpStatsTypes b)
 {
     b = (OfpStatsTypes)br.ReadUInt16();
     return(b);
 }
예제 #12
0
 public static OfpFlowModFlags Parse(this BeBinaryReader br, out OfpFlowModFlags b)
 {
     b = (OfpFlowModFlags)br.ReadUInt16();
     return(b);
 }
예제 #13
0
 public static OfpFlowModCommand Parse(this BeBinaryReader br, out OfpFlowModCommand b)
 {
     b = (OfpFlowModCommand)br.ReadUInt16();
     return(b);
 }
예제 #14
0
 public static OfpQueueProperties Parse(this BeBinaryReader br, out OfpQueueProperties b)
 {
     b = (OfpQueueProperties)br.ReadUInt16();
     return(b);
 }
예제 #15
0
 public static ushort Parse(this BeBinaryReader br, out ushort b)
 {
     b = br.ReadUInt16();
     return(b);
 }
예제 #16
0
        private void loadIBNKJaiV2(BeBinaryReader instReader)
        {
            long anchor         = 0;
            var  BaseAddress    = instReader.BaseStream.Position;
            var  current_header = instReader.ReadUInt32();

            if (current_header != 0x49424e4b) // Check to see if it equals IBNK
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("0x{0:X}", BaseAddress);
                throw new InvalidDataException("Scanned header is not an IBNK.");
            }

            var IBNKSize = instReader.ReadUInt32();

            id = instReader.ReadInt32();
            var flags = instReader.ReadUInt32();                  // usually 1, determines if the bank is melodic or used for sound effects. Usually the bank is melodic.

            instReader.BaseStream.Seek(0x10, SeekOrigin.Current); // Skip 16 bytes, always 0x00, please document if wrong.
            var i = 0;

            while (true)
            {
                anchor = instReader.BaseStream.Position; // Store current section base.
                i++;
                // Console.WriteLine("Iteration {0} 0x{1:X}", i,anchor);
                current_header = instReader.ReadUInt32();
                //  Console.WriteLine("GOT HD {0:X}", current_header);
                if (current_header == 0x00)
                {
                    break;                        // End of section.
                }
                else if (current_header < 0xFFFF) // Read below for explanation
                {
                    // I've noticed VERY RARELY, that the section pointer is wrong by two bytes. This sucks. So we check if it's less than two full bytes.
                    // If it is, we seek back 2 bytes then read again, and our alignment is fixed :).
                    // of course, this comes after our check to see if it's 0, which indicates end of section
                    instReader.BaseStream.Seek(-2, SeekOrigin.Current);
                    Console.WriteLine("[!] Misalignment detected in IBNK, new position 0x{0:X}", instReader.BaseStream.Position);
                    anchor         = instReader.BaseStream.Position; // 3/14/2019, i forgot this. It's S M R T to update your read base.
                    current_header = instReader.ReadUInt32();
                    Console.WriteLine("New header {0:X}", current_header);
                }
                var next_section = ReadJARCSizePointer(instReader); // if that works, go ahead and grab the 'pointer' to the next section.
                if (current_header < 0xFFFF)
                {
                    Console.WriteLine("Corrupt IBNK 0x{0:X}", BaseAddress);
                    break;
                }
                switch (current_header)
                {
                case 0x4F534354:                                            // OSCT
                case 0x52414E44:                                            // RAND
                case 0x454E5654:                                            // EVNT
                case 0x53454E53:                                            // SENS
                    instReader.BaseStream.Position = anchor + next_section; // Skip section.
                    break;

                case INST:
                {
                    var NewINST   = new Instrument();
                    var InstCount = instReader.ReadInt32();
                    NewINST.Keys = new InstrumentKey[0xF0];
                    for (int instid = 0; instid < InstCount; instid++)
                    {
                        current_header = instReader.ReadUInt32();
                        var iebase = instReader.BaseStream.Position;
                        if (current_header != Inst)
                        {
                            break;         // F**K.
                        }
                        NewINST.oscillator = instReader.ReadInt32();
                        NewINST.id         = instReader.ReadInt32();

                        instReader.ReadInt32();                 // cant figure out what these are.
                        var keyCounts = instReader.ReadInt32(); // How many key regions are in here.
                        int KeyHigh   = 0;
                        int KeyLow    = 0;
                        for (int k = 0; k < keyCounts; k++)
                        {
                            var NewKey = new InstrumentKey();
                            NewKey.keys = new InstrumentKeyVelocity[0x81];

                            byte key = instReader.ReadByte();                  // Read the key identifierr
                            KeyHigh = key;                                     // Set the highest key to what we just read.
                            instReader.BaseStream.Seek(3, SeekOrigin.Current); // 3 bytes, unused.
                            var VelocityRegionCount = instReader.ReadInt32();  // read the number of entries in the velocity region array\
                            if (VelocityRegionCount > 0x7F)
                            {
                                Console.WriteLine("Alignment is f****d, IBNK load aborted.");
                                Console.WriteLine("E: VelocityRegionCount is too thicc. {0} > 128", VelocityRegionCount);
                                Console.WriteLine("IBASE: 0x{0:X} + 0x{1:X} ({2:X})", anchor, iebase - anchor, (instReader.BaseStream.Position - anchor) - (iebase - anchor));

                                return;
                            }
                            for (int b = 0; b < VelocityRegionCount; b++)
                            {
                                var NewVelR = new InstrumentKeyVelocity();
                                int VelLow  = 0;
                                int VelHigh = 0;
                                {
                                    var velocity = instReader.ReadByte();              // The velocity of this key.
                                    VelHigh = velocity;
                                    instReader.BaseStream.Seek(3, SeekOrigin.Current); // Unused.
                                    NewVelR.velocity = velocity;
                                    NewVelR.wave     = instReader.ReadUInt16();        // This will be the ID of the wave inside of that wavesystem
                                    NewVelR.wsysid   = instReader.ReadUInt16();        // This will be the ID of the WAVESYSTEM that its in

                                    NewVelR.Volume = instReader.ReadSingle();          // Finetune, volume, float
                                    NewVelR.Pitch  = instReader.ReadSingle();          // finetune pitch, float.
                                    for (int idx = 0; idx < (VelHigh - VelLow); idx++) // See below for what this is doing
                                    {
                                        NewKey.keys[(VelLow + idx)] = NewVelR;
                                        NewKey.keys[127]            = NewVelR;
                                    }
                                    VelLow = VelHigh;
                                }
                            }
                            for (int idx = 0; idx < (KeyHigh - KeyLow); idx++) // The keys are gappy.
                            {
                                NewINST.Keys[(KeyLow + idx)] = NewKey;         // So we want to interpolate the previous keys across the empty ones, so that way it's a region
                                NewINST.Keys[127]            = NewKey;
                            }
                            KeyLow = KeyHigh;         // Set our new lowest key to the previous highest
                        }
                    }
                    instReader.BaseStream.Position = anchor + next_section;         // SAFETY.
                    break;
                }

                case PERC:

                    instReader.BaseStream.Position = anchor + next_section;
                    break;

                case 0x4C495354:                                            // LIST
                    instReader.BaseStream.Position = anchor + next_section; // Skip section
                    // Explanation: This is just a set of pointers relative to BaseAddress for the instruments, nothing special because we're
                    // already parsing them above.
                    break;

                default:
                    instReader.BaseStream.Position = anchor + next_section;     // Skip section.
                    break;
                }
            }
        }
예제 #17
0
        public JaiEventType loadNextOp()
        {
            if (OpcodeAddressStack.Count == 16)
            {
                OpcodeAddressStack.Dequeue();
            }
            if (OpcodeHistory.Count == 16)
            {
                OpcodeHistory.Dequeue();
            }

            OpcodeAddressStack.Enqueue((int)Sequence.BaseStream.Position); // push address to FIFO stack.

            State.current_address = (int)Sequence.BaseStream.Position;
            byte current_opcode = Sequence.ReadByte(); // Reads the current byte in front of the cursor.

            last_opcode = current_opcode;
            OpcodeHistory.Enqueue(current_opcode); // push opcode to FIFO stack



            if (current_opcode < 0x80)
            {
                State.note = current_opcode;                     // The note on event is laid out like a piano with 127 (0x7F1) keys.
                // So this means that the first 0x80 bytes are just pressing the individual keys.
                State.voice = Sequence.ReadByte();               // The next byte tells the voice, 0-8
                State.vel   = Sequence.ReadByte();               // And finally, the next byte will tell the velocity
                return(JaiEventType.NOTE_ON);                    // Return the note on event.
            }
            else if (current_opcode == (byte)JaiSeqEvent.WAIT_8) // Contrast to above, the opcode between these two is WAIT_U8
            {
                State.delay += Sequence.ReadByte();              // Add u8 ticks to the delay.

                return(JaiEventType.DELAY);
            }
            else if (current_opcode < 0x88)   // We already check if it's 0x80, so anything between here will be 0x81 and 0x87
            {
                // Only the first 7 bits are going to determine which voice we're stopping.
                State.voice = (byte)(current_opcode & 0x7F);
                return(JaiEventType.NOTE_OFF);
            }
            else   // Finally, we can fall into our CASE statement.
            {
                switch (current_opcode)
                {
                /* Delays and waits */
                case (byte)JaiSeqEvent.WAIT_16:          // Wait (UInt16)
                    State.delay = Sequence.ReadUInt16(); // Add to the state delay

                    return(JaiEventType.DELAY);

                case (byte)JaiSeqEvent.WAIT_VAR:     // Wait (VLQ) see readVlq function.
                    State.delay += Helpers.ReadVLQ(Sequence);
                    return(JaiEventType.DELAY);

                /* Logical jumps */

                case (byte)JaiSeqEvent.JUMP:                   // Unconditional jump
                    State.jump_mode    = 0;                    // Set jump mode to 0
                    State.jump_address = Sequence.ReadInt32(); // Absolute address.
                    return(JaiEventType.JUMP);

                case (byte)JaiSeqEvent.JUMP_COND:                             // Jump based on mode
                    State.jump_mode    = Sequence.ReadByte();
                    State.jump_address = (int)Helpers.ReadUInt24BE(Sequence); // pointer
                    return(JaiEventType.JUMP);

                case (byte)JaiSeqEvent.RET_COND:
                    State.jump_mode = Sequence.ReadByte();

                    return(JaiEventType.RET);

                case (byte)JaiSeqEvent.CALL_COND:
                    State.jump_mode    = Sequence.ReadByte();
                    State.jump_address = (int)Helpers.ReadUInt24BE(Sequence);
                    return(JaiEventType.CALL);

                case (byte)JaiSeqEvent.RET:
                    return(JaiEventType.RET);



                /* Tempo Control */

                case (byte)JaiSeqEvent.J2_SET_ARTIC:     // The very same.
                {
                    var type = Sequence.ReadByte();
                    var val  = Sequence.ReadInt16();
                    if (type == 0x62)
                    {
                        State.ppqn = val;
                    }
                    return(JaiEventType.TIME_BASE);
                }

                case (byte)JaiSeqEvent.TIME_BASE:     // Set ticks per quarter note.
                    State.ppqn = (short)(Sequence.ReadInt16());
                    //State.bpm = 100;
                    Console.WriteLine("Timebase ppqn set {0}", State.ppqn);
                    return(JaiEventType.TIME_BASE);

                case (byte)JaiSeqEvent.J2_TEMPO:  // Set BPM, Same format
                case (byte)JaiSeqEvent.TEMPO:     // Set BPM
                    State.bpm = (short)(Sequence.ReadInt16());
                    return(JaiEventType.TIME_BASE);

                /* Track Control */

                case (byte)JaiSeqEvent.OPEN_TRACK:
                    State.track_id      = Sequence.ReadByte();
                    State.track_address = (int)Helpers.ReadUInt24BE(Sequence);      // Pointer to track inside of BMS file (Absolute)
                    return(JaiEventType.NEW_TRACK);

                case (byte)JaiSeqEvent.FIN:
                    return(JaiEventType.HALT);

                case (byte)JaiSeqEvent.J2_SET_BANK:
                    State.voice_bank = Sequence.ReadByte();
                    return(JaiEventType.BANK_CHANGE);

                case (byte)JaiSeqEvent.J2_SET_PROG:
                    State.voice_program = Sequence.ReadByte();
                    return(JaiEventType.PROG_CHANGE);

                /* Parameter control */


                case (byte)JaiSeqEvent.J2_SET_PERF_8:
                    State.param       = Sequence.ReadByte();
                    State.param_value = Sequence.ReadByte();
                    return(JaiEventType.PARAM);

                case (byte)JaiSeqEvent.J2_SET_PERF_16:
                    State.param       = Sequence.ReadByte();
                    State.param_value = Sequence.ReadInt16();
                    return(JaiEventType.PARAM);

                case (byte)JaiSeqEvent.PARAM_SET_8:     // Set track parameters (Usually used for instruments)
                    State.param       = Sequence.ReadByte();
                    State.param_value = Sequence.ReadByte();
                    if (State.param == 0x20)   // 0x20 is bank change
                    {
                        State.voice_bank = (byte)State.param_value;
                        return(JaiEventType.BANK_CHANGE);
                    }
                    if (State.param == 0x21)     // 0x21 is program change
                    {
                        State.voice_program = (byte)State.param_value;
                        return(JaiEventType.PROG_CHANGE);
                    }
                    return(JaiEventType.PARAM);

                case (byte)JaiSeqEvent.PARAM_SET_16:     // Set track parameters (Usually used for instruments)
                    State.param       = Sequence.ReadByte();
                    State.param_value = Sequence.ReadInt16();
                    if (State.param == 0x20)     // 0x20 is bank change
                    {
                        State.voice_bank = (byte)State.param_value;
                        return(JaiEventType.BANK_CHANGE);
                    }
                    if (State.param == 0x21)     // 0x21 is program change
                    {
                        State.voice_program = (byte)State.param_value;
                        return(JaiEventType.PROG_CHANGE);
                    }
                    return(JaiEventType.PARAM);

                case (byte)JaiSeqEvent.PRINTF:
                    var    lastread = -1;
                    string v        = "";
                    while (lastread != 0)
                    {
                        lastread = Sequence.ReadByte();
                        v       += (char)lastread;
                    }
                    // Sequence.ReadByte();
                    Console.WriteLine(v);

                    return(JaiEventType.UNKNOWN);

                /* PERF Control*/

                /* Perf structure is as follows
                 * <byte> type
                 * <?> val
                 * (<?> dur)
                 */

                case (byte)JaiSeqEvent.PERF_U8_NODUR:
                    State.perf       = Sequence.ReadByte();
                    State.perf_value = Sequence.ReadByte();

                    State.perf_duration = 0;
                    State.perf_type     = 1;
                    State.perf_decimal  = ((double)State.perf_value / 0xFF);
                    return(JaiEventType.PERF);

                case (byte)JaiSeqEvent.PERF_U8_DUR_U8:
                    State.perf          = Sequence.ReadByte();
                    State.perf_value    = Sequence.ReadByte();
                    State.perf_duration = Sequence.ReadByte();
                    State.perf_type     = 1;
                    State.perf_decimal  = ((double)State.perf_value / 0xFF);
                    return(JaiEventType.PERF);

                case (byte)JaiSeqEvent.PERF_U8_DUR_U16:

                    State.perf          = Sequence.ReadByte();
                    State.perf_value    = Sequence.ReadByte();
                    State.perf_duration = Sequence.ReadUInt16();
                    State.perf_type     = 1;
                    State.perf_decimal  = ((double)State.perf_value / 0xFF);
                    return(JaiEventType.PERF);

                case (byte)JaiSeqEvent.PERF_S8_NODUR:
                {
                    State.perf = Sequence.ReadByte();
                    var b = Sequence.ReadByte();         // Lazy byte signage, apparently C#'s SByte is broken.
                    State.perf_value    = (b > 0x7F) ? b - 0xFF : b;
                    State.perf_duration = 0;
                    State.perf_type     = 2;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7F);
                    return(JaiEventType.PERF);
                }

                case (byte)JaiSeqEvent.PERF_S8_DUR_U8:
                {
                    State.perf = Sequence.ReadByte();
                    var b = Sequence.ReadByte();         // Lazy byte signage, apparently C#'s SByte is broken.
                    State.perf_value    = (b > 0x7F) ? b - 0xFF : b;
                    State.perf_duration = Sequence.ReadByte();
                    State.perf_type     = 2;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7F);
                    return(JaiEventType.PERF);
                }

                case (byte)JaiSeqEvent.PERF_S8_DUR_U16:
                {
                    State.perf = Sequence.ReadByte();
                    var b = Sequence.ReadByte();         // Lazy byte signage, apparently C#'s SByte is broken.
                    State.perf_value    = State.perf_value = (b > 0x7F) ? b - 0xFF : b;
                    State.perf_duration = Sequence.ReadUInt16();
                    State.perf_type     = 2;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7F);
                    return(JaiEventType.PERF);
                }

                case (byte)JaiSeqEvent.PERF_S16_NODUR:
                    State.perf          = Sequence.ReadByte();
                    State.perf_value    = Sequence.ReadInt16();
                    State.perf_duration = 0;
                    State.perf_type     = 3;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7FFF);
                    return(JaiEventType.PERF);

                case (byte)JaiSeqEvent.PERF_S16_DUR_U8:
                    State.perf          = Sequence.ReadByte();
                    State.perf_value    = Sequence.ReadInt16();
                    State.perf_duration = Sequence.ReadByte();
                    State.perf_type     = 3;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7FFF);
                    return(JaiEventType.PERF);

                case (byte)JaiSeqEvent.PERF_S16_DUR_U16:
                    State.perf          = Sequence.ReadByte();
                    State.perf_value    = Sequence.ReadInt16();
                    State.perf_duration = Sequence.ReadUInt16();
                    State.perf_type     = 3;
                    State.perf_decimal  = ((double)(State.perf_value) / 0x7FFF);
                    return(JaiEventType.PERF);


                /* J2 Opcodes */


                /* Unsure as of yet, but we have to keep alignment */
                case 0xE7:
                    skip(2);
                    // Console.WriteLine(Sequence.ReadByte());
                    //Console.WriteLine(Sequence.ReadByte());

                    return(JaiEventType.DEBUG);

                case 0xDD:
                case 0xED:
                    skip(3);
                    return(JaiEventType.UNKNOWN);

                case 0xEF:
                case 0xF9:
                case 0xE6:

                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xA0:
                case (byte)JaiSeqEvent.ADDR:     //
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xA3:
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xA5:
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xA7:
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xA9:
                    skip(4);
                    return(JaiEventType.UNKNOWN);

                case 0xAA:
                    skip(4);
                    return(JaiEventType.UNKNOWN);

                case 0xAD:
                    // State.delay += 0xFFFF;
                    // Add (byte) register.  + (short) value
                    //
                    skip(3);
                    return(JaiEventType.UNKNOWN);

                case 0xAE:
                    return(JaiEventType.UNKNOWN);

                case 0xB1:
                case 0xB2:
                case 0xB3:
                case 0xB4:
                case 0xB5:
                case 0xB6:
                case 0xB7:
                    int flag = Sequence.ReadByte();
                    if (flag == 0x40)
                    {
                        skip(2);
                    }
                    if (flag == 0x80)
                    {
                        skip(4);
                    }
                    return(JaiEventType.UNKNOWN);

                case 0xDB:

                case 0xDF:

                    skip(4);
                    return(JaiEventType.UNKNOWN);

                case 0xCB:
                case 0xBE:
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xCC:
                    skip(2);
                    return(JaiEventType.UNKNOWN);

                case 0xCF:
                    skip(1);
                    return(JaiEventType.UNKNOWN);

                case 0xD0:
                case 0xD1:
                case 0xD2:
                case 0xD5:
                case 0xD9:

                case 0xDE:
                case 0xDA:

                    skip(1);
                    return(JaiEventType.UNKNOWN);

                case 0xF1:
                case 0xF4:

                case 0xD6:
                    skip(1);
                    //Console.WriteLine(Sequence.ReadByte());
                    return(JaiEventType.DEBUG);

                case 0xBC:
                    return(JaiEventType.UNKNOWN);
                }
            }
            return(JaiEventType.UNKNOWN_ALIGN_FAIL);
        }
예제 #18
0
 public Move(BeBinaryReader br)
 {
     Tier                     = (Tier)br.ReadUInt16();
     BasePower                = br.ReadUInt16();
     MaxPower                 = br.ReadUInt16();
     Tp                       = br.ReadUInt16();
     Element                  = (Element)br.ReadUInt16();
     Status                   = (Status)br.ReadUInt16();
     OutputRange              = br.ReadUInt16();
     OutputRangeAssist        = br.ReadUInt16();
     EffectRange              = br.ReadUInt16();
     Unk4                     = br.ReadUInt16();
     CoopPartnersCount        = br.ReadUInt16();
     Unka                     = br.ReadUInt16();
     Unkb                     = br.ReadUInt16();
     Users                    = br.ReadMultipleUShort(10).ToArray();
     Partners                 = br.ReadMultipleUShort(10).ToArray();
     Unk5                     = br.ReadUInt16();
     Unk6                     = br.ReadUInt16();
     Unk7                     = br.ReadUInt16();
     Unk8                     = br.ReadUInt16();
     Unk9                     = br.ReadUInt16();
     Unk10                    = br.ReadUInt16();
     TextDescription          = br.ReadUInt16();
     Unk12                    = br.ReadUInt16();
     Unk13                    = br.ReadUInt16();
     Unk14                    = br.ReadUInt16();
     TextUser                 = br.ReadUInt16();
     Unk16                    = br.ReadUInt16();
     Unk17                    = br.ReadUInt16();
     Unk18                    = br.ReadUInt16();
     Unk19                    = br.ReadUInt16();
     Unk20                    = br.ReadUInt16();
     Unk21                    = br.ReadUInt16();
     Unk22                    = br.ReadUInt16();
     Unk23                    = br.ReadUInt16();
     Unk24                    = br.ReadUInt16();
     Unk25                    = br.ReadUInt16();
     Unk26                    = br.ReadUInt16();
     Unk27                    = br.ReadUInt16();
     Unk28                    = br.ReadUInt16();
     Unk29                    = br.ReadUInt16();
     Unk30                    = br.ReadUInt16();
     Unk31                    = br.ReadUInt16();
     Unk32                    = br.ReadUInt16();
     Unk33                    = br.ReadUInt16();
     Unk34                    = br.ReadUInt16();
     Unk35                    = br.ReadUInt16();
     Unk36                    = br.ReadUInt16();
     Unk37                    = br.ReadUInt16();
     Unk38                    = br.ReadUInt16();
     PowerUpIndicator         = (PowerUpIndicator)br.ReadUInt16();
     InvocationAnimationTimer = br.ReadUInt16();
     Unk39                    = br.ReadUInt16();
 }