예제 #1
0
        public static uint FromVector3(Vector3 vec, int intPart = 0, int fracPart = 9)
        {
            var buffer = new byte[] { 0x00, 0x00 };

            var coords = new ushort[3];

            var m = new MemoryStream(buffer);

            var ew = new EndianBinaryWriterEx(m, Endianness.LittleEndian);
            var er = new EndianBinaryReaderEx(m, Endianness.LittleEndian);

            ew.WriteFixedPoint(vec.X, true, intPart, fracPart);
            m.Position = 0;
            coords[0]  = er.ReadUInt16();

            m.Position = 0;
            ew.WriteFixedPoint(vec.Y, true, intPart, fracPart);
            m.Position = 0;
            coords[1]  = er.ReadUInt16();

            m.Position = 0;
            ew.WriteFixedPoint(vec.Z, true, intPart, fracPart);
            m.Position = 0;
            coords[2]  = er.ReadUInt16();

            m.Close();

            var res = (uint)(coords[0] | (coords[1] << 10) | (coords[2] << 20));

            return(res);
        }
예제 #2
0
        public static byte[] Encode(IEnumerable <DisplayListCommand> commands)
        {
            var m  = new MemoryStream();
            var ew = new EndianBinaryWriterEx(m, Endianness.LittleEndian);

            int offset = 0;
            int packed = 0;

            var cmdList = commands.ToList();

            var nops = (cmdList.Count % 4) == 0 ? 0 : 4 - (cmdList.Count % 4);

            //Add NOPs at the end
            for (int i = 0; i < nops; i++)
            {
                cmdList.Add(new DisplayListCommand(G3dCommand.Nop));
            }

            var commandQueue = new Queue <DisplayListCommand>();

            bool param0Flag = false;

            void Flush()
            {
                packed = 0;

                var count = commandQueue.Count;

                for (int i = 0; i < count; i++)
                {
                    var cmd = commandQueue.Dequeue();

                    //m.Position = offset;

                    switch (cmd.G3dCommand)
                    {
                    default:
                    case G3dCommand.Identity:
                    case G3dCommand.PushMatrix:
                    case G3dCommand.End:
                    case G3dCommand.Nop:
                        break;

                    case G3dCommand.TexCoord:
                        ew.WriteFixedPoint(cmd.RealArgs[0], true, 11, 4);
                        ew.WriteFixedPoint(cmd.RealArgs[1], true, 11, 4);
                        offset += 4;
                        break;

                    case G3dCommand.VertexXY:
                    case G3dCommand.VertexXZ:
                    case G3dCommand.VertexYZ:
                        ew.WriteFx16s(cmd.RealArgs);
                        offset += 4;
                        break;

                    case G3dCommand.Begin:
                    case G3dCommand.RestoreMatrix:
                        ew.Write(cmd.IntArgs[0]);
                        offset += 4;
                        break;

                    case G3dCommand.VertexDiff:
                        var vec2 = VecFx10.FromVector3((cmd.RealArgs[0] * 8, cmd.RealArgs[1] * 8,
                                                        cmd.RealArgs[2] * 8));
                        ew.Write(vec2);
                        offset += 4;
                        break;

                    case G3dCommand.VertexShort:
                        var vec3 = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2]), 3,
                                                       6);
                        ew.Write(vec3);
                        offset += 4;
                        break;

                    case G3dCommand.Normal:
                        var vec = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2]));
                        ew.Write(vec);
                        offset += 4;
                        break;

                    case G3dCommand.Color:
                        var color = GFXUtil.ConvertColorFormat(
                            (uint)Color.FromArgb(0, (int)cmd.IntArgs[0], (int)cmd.IntArgs[1],
                                                 (int)cmd.IntArgs[2]).ToArgb(),
                            ColorFormat.ARGB8888, ColorFormat.ABGR1555);
                        ew.Write(color);
                        offset += 4;
                        break;

                    case G3dCommand.Vertex:
                        ew.WriteFx16s(cmd.RealArgs);
                        ew.Write((ushort)0);
                        offset += 8;
                        break;
                    }
                }

                if (param0Flag)
                {
                    ew.Write(0);
                    offset += 4;

                    param0Flag = false;
                }
            }

            foreach (var command in cmdList)
            {
                if (command.G3dCommand != G3dCommand.Nop)
                {
                    param0Flag = packed > 0 && (command.G3dCommand == G3dCommand.Identity ||
                                                command.G3dCommand == G3dCommand.PushMatrix ||
                                                command.G3dCommand == G3dCommand.End);
                }

                //m.Position = offset;

                commandQueue.Enqueue(command);
                ew.Write((byte)command.G3dCommand);
                packed++;
                offset++;

                if (packed == 4)
                {
                    Flush();
                }
            }

            var dl = m.ToArray();

            m.Close();

            return(dl);
        }