//private bool CheckAddressValidity(byte bankNo, uint offset)
        //{
        //    if (offset == 0) return false;
        //    if (!MemoryManager.Instance.HasBank(bankNo))
        //    {
        //        ErrorLog.Add(string.Format("- Warning: Segment 0x{0:X2} was not initialized, cannot access offset 0x{0:X6}!\n", bankNo, offset));
        //        return false;
        //    }
        //    else if (!MemoryManager.Instance.LocateBank(bankNo, offset).IsValid())
        //    {
        //        ErrorLog.Add(string.Format("- Warning: Offset 0x{0:X6} is out of bounds for segment 0x{0:X2}!\n", offset, bankNo));
        //        return false;
        //    }
        //    return true;
        //}
        public void StartReadingLevelDataAt(byte bankNo, uint index)
        {
            //This will need to parse the commands from the level data and pick off the F3DEX
            SFGfx.sv_ClearStructures(false);
            SFGfx.gl_ClearRenderer(true);
            SFGfx.GameObjects.Clear();
            SFGfx.GameObjCount = 0;

            byte limbCount = MemoryManager.Instance.ReadByte(bankNo, index + 3); //This should be the number of limbs

            //First 4 bytes are things I don't know (+ the limb count), next 8 bytes are header pointers, then it starts the data
            index += 0xC;

            List<stuffToAdd> hierarchyTesting = new List<stuffToAdd>();
            stuffToAdd topStuff = new stuffToAdd();

            for(int i = 0; i < limbCount; i++)
            {
                if (!CheckAddressValidity(bankNo, index)) break;

                SFGfx.GameObject newObj = new SFGfx.GameObject();

                newObj.LvlPos = 0;
                newObj.Z = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0x4);
                newObj.Y = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0x8);
                newObj.X = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0xC);
                newObj.XRot = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x10) / 182.0444444);
                newObj.YRot = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x12) / 182.0444444);
                newObj.ZRot = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x14) / 182.0444444);
                newObj.ID = 0;
                newObj.Unk = 0;

                // default dlist offset to 0
                newObj.DListOffset = MemoryManager.Instance.ReadUInt(bankNo, index);

                //// if object id == 0xffff, break out because this marks end of data!
                //if (newObj.ID == 0xFFFF) break;

                //// if object id < 0x190, get offset like this
                //if (newObj.ID < 0x190)
                //{
                //    //NOTE: SET -2 TO DMA 1
                //    newObj.DListOffset = MemoryManager.Instance.ReadUInt((byte)0xFF, (0xC72E4 + ((uint)newObj.ID * 0x24)));
                //}

                // dlist offset sanity checks
                if (((newObj.DListOffset & 3) != 0x0) ||							// dlist offset not 4 byte aligned
                  ((newObj.DListOffset & 0xFF000000) == 0x80000000))	// dlist offset lies in ram
                    newObj.DListOffset = 0x00;

                stuffToAdd newHier = new stuffToAdd();
                newHier.id = index + 0x04000000;
                newHier.siblingID = MemoryManager.Instance.ReadUInt(bankNo, index + 0x18);
                newHier.childID = MemoryManager.Instance.ReadUInt(bankNo, index + 0x1C);

                index += 0x20;

                //if (newObj.DListOffset != 0x00)
                //{
                    SFGfx.GameObjects.Add(newObj);

                    newHier.gameObjectCount = SFGfx.GameObjCount;

                    SFGfx.GameObjCount++;
                //}
                //else
                 //   newHier.gameObjectCount = -1;

                hierarchyTesting.Add(newHier);
            }

            //Apply hierarchy stuff. For now, assume that there is only 1 at the top which is not a child
            stuffToAdd topLevel = hierarchyTesting.SingleOrDefault(x => hierarchyTesting.Count(y => y.childID == x.id || y.siblingID == x.id) == 0);
            Queue<stuffToAdd> nextTopLevel = new Queue<stuffToAdd>();
            while (topLevel.id != 0)
            {
                //Apply transformations each step down
                if (topLevel.childID != 0)
                {
                    SFGfx.GameObject parentObject = SFGfx.GameObjects[topLevel.gameObjectCount];

                    stuffToAdd childNode = hierarchyTesting.SingleOrDefault(x => topLevel.childID == x.id);
                    while (childNode.id != 0)
                    {
                        //Do the adding here
                        SFGfx.GameObject gameObject = SFGfx.GameObjects[childNode.gameObjectCount];

                        gameObject.X += parentObject.X;
                        gameObject.Y += parentObject.Y;
                        gameObject.Z += parentObject.Z;
                        gameObject.XRot += parentObject.XRot;
                        gameObject.YRot += parentObject.YRot;
                        gameObject.ZRot += parentObject.ZRot;

                        SFGfx.GameObjects[childNode.gameObjectCount] = gameObject;

                        if (childNode.siblingID != 0)
                            childNode = hierarchyTesting.SingleOrDefault(x => childNode.siblingID == x.id);
                        else
                            childNode.id = 0;
                    }
                }

                if(topLevel.siblingID != 0)
                    nextTopLevel.Enqueue(hierarchyTesting.SingleOrDefault(x => topLevel.siblingID == x.id));
                if(topLevel.childID != 0)
                    nextTopLevel.Enqueue(hierarchyTesting.SingleOrDefault(x => topLevel.childID == x.id));

                if (nextTopLevel.Count > 0)
                    topLevel = nextTopLevel.Dequeue();
                else
                    topLevel.id = 0;
            }

            for (int j = hierarchyTesting.Count - 1; j >= 0; j--)
            {
                if (SFGfx.GameObjects[hierarchyTesting[j].gameObjectCount].DListOffset == 0x0)
                {
                    SFGfx.GameObjects.RemoveAt(hierarchyTesting[j].gameObjectCount);
                    SFGfx.GameObjCount--;
                }
            }

            ExecuteDisplayLists();

            SFCamera.Reset();
        }
Exemple #2
0
        //private bool CheckAddressValidity(byte bankNo, uint offset)
        //{
        //    if (offset == 0) return false;

        //    if (!MemoryManager.Instance.HasBank(bankNo))
        //    {
        //        ErrorLog.Add(string.Format("- Warning: Segment 0x{0:X2} was not initialized, cannot access offset 0x{0:X6}!\n", bankNo, offset));
        //        return false;
        //    }
        //    else if (!MemoryManager.Instance.LocateBank(bankNo, offset).IsValid())
        //    {
        //        ErrorLog.Add(string.Format("- Warning: Offset 0x{0:X6} is out of bounds for segment 0x{0:X2}!\n", offset, bankNo));
        //        return false;
        //    }

        //    return true;
        //}

        public void StartReadingLevelDataAt(byte bankNo, uint index)
        {
            //This will need to parse the commands from the level data and pick off the F3DEX
            SFGfx.sv_ClearStructures(false);
            SFGfx.gl_ClearRenderer(true);
            SFGfx.GameObjects.Clear();
            SFGfx.GameObjCount = 0;

            byte limbCount = MemoryManager.Instance.ReadByte(bankNo, index + 3); //This should be the number of limbs

            //First 4 bytes are things I don't know (+ the limb count), next 8 bytes are header pointers, then it starts the data
            index += 0xC;

            List <stuffToAdd> hierarchyTesting = new List <stuffToAdd>();
            stuffToAdd        topStuff         = new stuffToAdd();

            for (int i = 0; i < limbCount; i++)
            {
                if (!CheckAddressValidity(bankNo, index))
                {
                    break;
                }

                SFGfx.GameObject newObj = new SFGfx.GameObject();


                newObj.LvlPos = 0;
                newObj.Z      = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0x4);
                newObj.Y      = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0x8);
                newObj.X      = (short)MemoryManager.Instance.ReadFloat(bankNo, index + 0xC);
                newObj.XRot   = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x10) / 182.0444444);
                newObj.YRot   = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x12) / 182.0444444);
                newObj.ZRot   = (short)((double)MemoryManager.Instance.ReadUShort(bankNo, index + 0x14) / 182.0444444);
                newObj.ID     = 0;
                newObj.Unk    = 0;

                // default dlist offset to 0
                newObj.DListOffset = MemoryManager.Instance.ReadUInt(bankNo, index);

                //// if object id == 0xffff, break out because this marks end of data!
                //if (newObj.ID == 0xFFFF) break;

                //// if object id < 0x190, get offset like this
                //if (newObj.ID < 0x190)
                //{
                //    //NOTE: SET -2 TO DMA 1
                //    newObj.DListOffset = MemoryManager.Instance.ReadUInt((byte)0xFF, (0xC72E4 + ((uint)newObj.ID * 0x24)));
                //}

                // dlist offset sanity checks
                if (((newObj.DListOffset & 3) != 0x0) ||                // dlist offset not 4 byte aligned
                    ((newObj.DListOffset & 0xFF000000) == 0x80000000))  // dlist offset lies in ram
                {
                    newObj.DListOffset = 0x00;
                }


                stuffToAdd newHier = new stuffToAdd();
                newHier.id        = index + 0x04000000;
                newHier.siblingID = MemoryManager.Instance.ReadUInt(bankNo, index + 0x18);
                newHier.childID   = MemoryManager.Instance.ReadUInt(bankNo, index + 0x1C);

                index += 0x20;

                //if (newObj.DListOffset != 0x00)
                //{
                SFGfx.GameObjects.Add(newObj);

                newHier.gameObjectCount = SFGfx.GameObjCount;

                SFGfx.GameObjCount++;
                //}
                //else
                //   newHier.gameObjectCount = -1;

                hierarchyTesting.Add(newHier);
            }

            //Apply hierarchy stuff. For now, assume that there is only 1 at the top which is not a child
            stuffToAdd         topLevel     = hierarchyTesting.SingleOrDefault(x => hierarchyTesting.Count(y => y.childID == x.id || y.siblingID == x.id) == 0);
            Queue <stuffToAdd> nextTopLevel = new Queue <stuffToAdd>();

            while (topLevel.id != 0)
            {
                //Apply transformations each step down
                if (topLevel.childID != 0)
                {
                    SFGfx.GameObject parentObject = SFGfx.GameObjects[topLevel.gameObjectCount];

                    stuffToAdd childNode = hierarchyTesting.SingleOrDefault(x => topLevel.childID == x.id);
                    while (childNode.id != 0)
                    {
                        //Do the adding here
                        SFGfx.GameObject gameObject = SFGfx.GameObjects[childNode.gameObjectCount];

                        gameObject.X    += parentObject.X;
                        gameObject.Y    += parentObject.Y;
                        gameObject.Z    += parentObject.Z;
                        gameObject.XRot += parentObject.XRot;
                        gameObject.YRot += parentObject.YRot;
                        gameObject.ZRot += parentObject.ZRot;

                        SFGfx.GameObjects[childNode.gameObjectCount] = gameObject;

                        if (childNode.siblingID != 0)
                        {
                            childNode = hierarchyTesting.SingleOrDefault(x => childNode.siblingID == x.id);
                        }
                        else
                        {
                            childNode.id = 0;
                        }
                    }
                }

                if (topLevel.siblingID != 0)
                {
                    nextTopLevel.Enqueue(hierarchyTesting.SingleOrDefault(x => topLevel.siblingID == x.id));
                }
                if (topLevel.childID != 0)
                {
                    nextTopLevel.Enqueue(hierarchyTesting.SingleOrDefault(x => topLevel.childID == x.id));
                }

                if (nextTopLevel.Count > 0)
                {
                    topLevel = nextTopLevel.Dequeue();
                }
                else
                {
                    topLevel.id = 0;
                }
            }

            for (int j = hierarchyTesting.Count - 1; j >= 0; j--)
            {
                if (SFGfx.GameObjects[hierarchyTesting[j].gameObjectCount].DListOffset == 0x0)
                {
                    SFGfx.GameObjects.RemoveAt(hierarchyTesting[j].gameObjectCount);
                    SFGfx.GameObjCount--;
                }
            }

            ExecuteDisplayLists();

            SFCamera.Reset();
        }