Ejemplo n.º 1
0
        private static void CMD_39(ref Level lvl, ref string desc, byte[] cmd, byte?areaID)
        {
            if (cmd.Length < 8)
            {
                return;
            }
            ROM  rom = ROM.Instance;
            uint pos = bytesToInt(cmd, 4, 4);

            desc = "Place macro objects loaded from address 0x" + pos.ToString("X8");

            byte[] data = rom.getDataFromSegmentAddress_safe(pos, 10, null);

            lvl.getCurrentArea().MacroObjects.Clear();
            bool endList = false;

            while (!endList)
            {
                //rom.printArray(data, 10);
                uint id = bytesToInt(data, 0, 2) & 0x1FF;
                if (id == 0 || id == 0x1E)
                {
                    break;
                }
                Object3D newObj = new Object3D();
                if (rom.isSegmentMIO0(cmd[4], areaID))
                {
                    newObj.MakeReadOnly();
                    newObj.Address = "N/A";
                }
                else
                {
                    newObj.Address = "0x" + rom.decodeSegmentAddress(pos, areaID).ToString("X");
                }

                uint   table_off = (id - 0x1F) * 8;
                byte[] entryData = rom.getSubArray_safe(rom.Bytes, Globals.macro_preset_table + table_off, 8);
                newObj.level = lvl;
                newObj.createdFromLevelScriptCommand = Object3D.FROM_LS_CMD.CMD_39;
                newObj.setBehaviorFromAddress(bytesToInt(entryData, 0, 4));
                newObj.HideProperty(Object3D.FLAGS.ROTATION_X);
                newObj.HideProperty(Object3D.FLAGS.ROTATION_Z);
                newObj.HideProperty(Object3D.FLAGS.BPARAM_3);
                newObj.HideProperty(Object3D.FLAGS.BPARAM_4);
                newObj.ModelID = entryData[5];
                ushort firstAndSecond = (ushort)bytesToInt(data, 0, 2);
                newObj.setPresetID((ushort)(firstAndSecond & 0x1FF));
                newObj.yRot = (short)((firstAndSecond >> 9) * 2.8125);
                newObj.xPos = (short)bytesToInt(data, 2, 2);
                newObj.yPos = (short)bytesToInt(data, 4, 2);
                newObj.zPos = (short)bytesToInt(data, 6, 2);
                newObj.DontShowActs();
                newObj.MakeBehaviorReadOnly(true);
                newObj.MakeModelIDReadOnly(true);
                ushort bp = (ushort)bytesToInt(data, 8, 2);
                if (data[8] != 0)
                {
                    newObj.BehaviorParameter1 = data[8];
                }
                else
                {
                    newObj.BehaviorParameter1 = entryData[6];
                }

                if (data[9] != 0)
                {
                    newObj.BehaviorParameter2 = data[9];
                }
                else
                {
                    newObj.BehaviorParameter2 = entryData[7];
                }

                lvl.getCurrentArea().MacroObjects.Add(newObj);
                pos += 10;
                data = rom.getDataFromSegmentAddress_safe(pos, 10, null);
            }
            //uint end = bytesToInt(cmd, 8, 4);
            //rom.setSegment(seg, start, end, false);
        }
Ejemplo n.º 2
0
        /* Process collision map, Special Objects, and waterboxes. */
        private static void CMD_2E(ref Level lvl, ref string desc, byte[] cmd, byte?areaID)
        {
            ROM rom = ROM.Instance;

            if (cmd.Length < 8)
            {
                return;
            }
            desc = "Load collision, and place special objects from address 0x" + bytesToInt(cmd, 4, 4).ToString("X8");
            ushort sub_cmd = 0x40;
            byte   segment = cmd[4];
            uint   off     = bytesToInt(cmd, 5, 3);

            byte[] data = rom.getSegment(segment, areaID);
            sub_cmd = (ushort)bytesToInt(data, (int)off, 2);

            // Check if the data is actually collision data.
            if (data[off] != 0x00 || data[off + 1] != 0x40)
            {
                return;
            }

            CollisionMap cmap      = lvl.getCurrentArea().collision;
            uint         num_verts = (ushort)bytesToInt(data, (int)off + 2, 2);

            off += 4;
            for (int i = 0; i < num_verts; i++)
            {
                short x = (short)bytesToInt(data, (int)off + 0, 2);
                short y = (short)bytesToInt(data, (int)off + 2, 2);
                short z = (short)bytesToInt(data, (int)off + 4, 2);
                cmap.AddVertex(new OpenTK.Vector3(x, y, z));
                off += 6;
            }

            while (sub_cmd != 0x0041)
            {
                sub_cmd = (ushort)bytesToInt(data, (int)off, 2);
                //Console.WriteLine(sub_cmd.ToString("X8"));
                if (sub_cmd == 0x0041)
                {
                    break;
                }
                //rom.printArraySection(data, (int)off, 4 + (int)collisionLength(sub_cmd));
                cmap.NewTriangleList((int)bytesToInt(data, (int)off, 2));
                uint num_tri = (ushort)bytesToInt(data, (int)off + 2, 2);
                uint col_len = collisionLength(sub_cmd);
                off += 4;
                for (int i = 0; i < num_tri; i++)
                {
                    uint a = bytesToInt(data, (int)off + 0, 2);
                    uint b = bytesToInt(data, (int)off + 2, 2);
                    uint c = bytesToInt(data, (int)off + 4, 2);
                    cmap.AddTriangle(a, b, c);
                    off += col_len;
                }
            }
            cmap.buildCollisionMap();
            off += 2;
            bool end = false;

            while (!end)
            {
                sub_cmd = (ushort)bytesToInt(data, (int)off, 2);
                switch (sub_cmd)
                {
                case 0x0042:
                    end = true;
                    break;

                case 0x0043:
                    uint num_obj = (ushort)bytesToInt(data, (int)off + 2, 2);
                    off += 4;
                    for (int i = 0; i < num_obj; i++)
                    {
                        ushort   obj_id  = (ushort)bytesToInt(data, (int)off, 2);
                        byte[]   entry   = getSpecialObjectEntry((byte)obj_id);
                        uint     obj_len = getSpecialObjectLength(obj_id);
                        Object3D newObj  = new Object3D();
                        if (rom.isSegmentMIO0(segment, areaID))
                        {
                            newObj.MakeReadOnly();
                            newObj.Address = "N/A";
                        }
                        else
                        {
                            newObj.Address = "0x" + rom.decodeSegmentAddress(segment, off, areaID).ToString("X");
                        }
                        newObj.setPresetID(obj_id);
                        newObj.level = lvl;
                        newObj.HideProperty(Object3D.FLAGS.ROTATION_X);
                        newObj.HideProperty(Object3D.FLAGS.ROTATION_Z);
                        newObj.HideProperty(Object3D.FLAGS.BPARAM_3);
                        newObj.HideProperty(Object3D.FLAGS.BPARAM_4);
                        newObj.xPos = (short)bytesToInt(data, (int)off + 2, 2);
                        newObj.yPos = (short)bytesToInt(data, (int)off + 4, 2);
                        newObj.zPos = (short)bytesToInt(data, (int)off + 6, 2);
                        newObj.BehaviorParameter1 = entry[1];
                        newObj.BehaviorParameter2 = entry[2];
                        newObj.MakeBehaviorReadOnly(true);
                        newObj.MakeModelIDReadOnly(true);
                        if (obj_len > 8)
                        {
                            newObj.yRot = (short)(bytesToInt(data, (int)off + 8, 2) * 1.40625);
                            if (obj_len > 10)
                            {
                                newObj.BehaviorParameter1            = data[off + 10];
                                newObj.BehaviorParameter2            = data[off + 11];
                                newObj.createdFromLevelScriptCommand = Object3D.FROM_LS_CMD.CMD_2E_12;
                                lvl.AddSpecialObjectPreset_12(obj_id, entry[3],
                                                              bytesToInt(entry, 4, 4), data[off + 10], data[off + 11]);
                            }
                            else
                            {
                                lvl.AddSpecialObjectPreset_10(obj_id, entry[3], bytesToInt(entry, 4, 4));
                                newObj.HideProperty(Object3D.FLAGS.BPARAM_1);
                                newObj.HideProperty(Object3D.FLAGS.BPARAM_2);
                                newObj.createdFromLevelScriptCommand = Object3D.FROM_LS_CMD.CMD_2E_10;
                            }
                        }
                        else
                        {
                            lvl.AddSpecialObjectPreset_8(obj_id, entry[3], bytesToInt(entry, 4, 4));
                            newObj.HideProperty(Object3D.FLAGS.BPARAM_1);
                            newObj.HideProperty(Object3D.FLAGS.BPARAM_2);
                            newObj.HideProperty(Object3D.FLAGS.ROTATION_Y);
                            newObj.createdFromLevelScriptCommand = Object3D.FROM_LS_CMD.CMD_2E_8;
                        }
                        newObj.ModelID = entry[3];
                        uint behavior = bytesToInt(entry, 4, 4);
                        newObj.setBehaviorFromAddress(behavior);
                        newObj.DontShowActs();
                        if (behavior != 0)
                        {
                            lvl.getCurrentArea().SpecialObjects.Add(newObj);
                        }
                        off += obj_len;
                    }
                    break;

                case 0x0044:
                    // Also skipping water boxes. Will come back to it later.
                    uint num_boxes = (ushort)bytesToInt(data, (int)off + 2, 2);
                    off += 4 + (num_boxes * 0xC);
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        private static void CMD_39(ref Level lvl, byte[] cmd, ROM rom)
        {
            if (cmd.Length < 8)
            {
                return;
            }
            uint pos = bytesToInt(cmd, 4, 4);

            byte[] data = rom.getDataFromSegmentAddress_safe(pos, 10);

            lvl.getCurrentArea().MacroObjects.Clear();
            bool endList = false;

            while (!endList)
            {
                //rom.printArray(data, 10);
                uint id = bytesToInt(data, 0, 2) & 0x1FF;
                if (id == 0 || id == 0x1E)
                {
                    break;
                }
                Object3D newObj = new Object3D();
                if (rom.isSegmentMIO0(cmd[4]))
                {
                    newObj.MakeReadOnly();
                    newObj.Address = "N/A";
                }
                else
                {
                    newObj.Address = "0x" + rom.decodeSegmentAddress(pos).ToString("X");
                }

                uint   table_off = (id - 0x1F) * 8;
                byte[] entryData = rom.getSubArray(rom.Bytes, Globals.macro_preset_table + table_off, 8);
                newObj.level = lvl;
                newObj.setBehaviorFromAddress(bytesToInt(entryData, 0, 4));
                newObj.HideProperty(Object3D.FLAGS.ROTATION_X);
                newObj.HideProperty(Object3D.FLAGS.ROTATION_Z);
                newObj.HideProperty(Object3D.FLAGS.BPARAM_3);
                newObj.HideProperty(Object3D.FLAGS.BPARAM_4);
                newObj.ModelID = entryData[5];
                newObj.setPresetID((ushort)(data[0] & 0x1FF));
                newObj.yRot = (short)((data[0] >> 4) * 22.5f);
                newObj.xPos = (short)bytesToInt(data, 2, 2);
                newObj.yPos = (short)bytesToInt(data, 4, 2);
                newObj.zPos = (short)bytesToInt(data, 6, 2);
                newObj.DontShowActs();
                newObj.MakeBehaviorReadOnly(true);
                newObj.MakeModelIDReadOnly(true);
                ushort bp = (ushort)bytesToInt(data, 8, 2);
                if (data[8] != 0)
                {
                    newObj.BehaviorParameter1 = data[8];
                }
                else
                {
                    newObj.BehaviorParameter1 = entryData[6];
                }

                if (data[9] != 0)
                {
                    newObj.BehaviorParameter2 = data[9];
                }
                else
                {
                    newObj.BehaviorParameter2 = entryData[7];
                }

                lvl.getCurrentArea().MacroObjects.Add(newObj);
                pos += 10;
                data = rom.getDataFromSegmentAddress_safe(pos, 10);
            }
            //uint end = bytesToInt(cmd, 8, 4);
            //rom.setSegment(seg, start, end, false);
        }