Inheritance: IGameDataStructure
        public SFLevelObject(int offset, byte[] bytes)
        {
            Offset = offset;

            AdvancedScript = null;

            LoadFromBytes(bytes);
        }
        public SFLevelObject(int offset, byte[] bytes)
        {
            Offset = offset;

            AdvancedScript = null;

            LoadFromBytes(bytes);
        }
Example #3
0
        public void LoadROMResources()
        {
            if (_resourcesLoaded)
                return;

            //Here we'll go through the level files/reference file, and then create the F3DEX objects and link them to the
            // simple object list in the reference file
            F3DEXParser _f3dex = new F3DEXParser();

            //_f3dex.InitInvalidModels();

            //Init the simple objects to use the invalid box dlist indices
            foreach (RefSimpleLevelObject obj in _referenceDMA.SimpleObjects)
            {
                obj.GLDisplayListOffset = F3DEXParser.InvalidBox;
            }

            //Init the simple objects to use the invalid box dlist indices
            foreach (RefAdvancedLevelObject obj in _referenceDMA.AdvancedObjects)
            {
                obj.GLDisplayListOffset = F3DEXParser.InvalidBox;
            }

            //Make a list of the level indices, just for optimization sake later on
            List<int> levelIndices = StarFoxRomInfo.LevelIndexAndDMAs.ToList();

            foreach (LevelDMAFile level in _levelDMAs)
            {
                byte[] levelBytes = level.GetAsBytes();

                Dictionary<int, byte[]> ramBytes = new Dictionary<int, byte[]>();
                int count = _referenceDMA.RAMTable.Count(r => r.Seg6Start == level.DMAInfo.PStart);
                int xs = count;
                RAMTableEntry ramInfo = _referenceDMA.RAMTable.FirstOrDefault(r => r.Seg6Start == level.DMAInfo.PStart);
                if (ramInfo != null)
                {
                    //Load it all in!!
                    DMAFile dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg1Start);
                    if(dma == null)
                        ramBytes.Add(1, null);
                    else
                        ramBytes.Add(1, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg2Start);
                    if (dma == null)
                        ramBytes.Add(2, null);
                    else
                        ramBytes.Add(2, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg3Start);
                    if (dma == null)
                        ramBytes.Add(3, null);
                    else
                        ramBytes.Add(3, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg4Start);
                    if (dma == null)
                        ramBytes.Add(4, null);
                    else
                        ramBytes.Add(4, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg5Start);
                    if (dma == null)
                        ramBytes.Add(5, null);
                    else
                        ramBytes.Add(5, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg6Start);
                    if (dma == null)
                        ramBytes.Add(6, null);
                    else
                        ramBytes.Add(6, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg7Start);
                    if (dma == null)
                        ramBytes.Add(7, null);
                    else
                        ramBytes.Add(7, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg8Start);
                    if (dma == null)
                        ramBytes.Add(8, null);
                    else
                        ramBytes.Add(8, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.Seg9Start);
                    if (dma == null)
                        ramBytes.Add(9, null);
                    else
                        ramBytes.Add(9, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegAStart);
                    if (dma == null)
                        ramBytes.Add(0xA, null);
                    else
                        ramBytes.Add(0xA, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegBStart);
                    if (dma == null)
                        ramBytes.Add(0xB, null);
                    else
                        ramBytes.Add(0xB, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegCStart);
                    if (dma == null)
                        ramBytes.Add(0xC, null);
                    else
                        ramBytes.Add(0xC, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegDStart);
                    if (dma == null)
                        ramBytes.Add(0xD, null);
                    else
                        ramBytes.Add(0xD, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegEStart);
                    if (dma == null)
                        ramBytes.Add(0xE, null);
                    else
                        ramBytes.Add(0xE, dma.GetAsBytes());

                    dma = SF64ROM.Instance.DMATable.SingleOrDefault(d => d.DMAInfo.PStart == ramInfo.SegFStart);
                    if (dma == null)
                        ramBytes.Add(0xF, null);
                    else
                        ramBytes.Add(0xF, dma.GetAsBytes());
                }

                foreach(SFLevelObject obj in level.LevelObjects)
                {
                    //We know that the 0x190 is the limit for the simple objects
                    if (obj.ID < 0x190)
                    {
                        obj.DListOffset = _referenceDMA.SimpleObjects[obj.ID].DListOffset;

                        // dlist offset sanity checks
                        if (((obj.DListOffset & 4) != 0x0) ||							// dlist offset not 4 byte aligned
                            ((obj.DListOffset & 0xFF000000) == 0x80000000) ||	// dlist offset lies in ram, leave it alone for now
                            ((obj.DListOffset & 0xFF000000) == 0x00000000))	// invalid dlist
                            obj.DListOffset = 0x00;

                        else
                        {
                            byte[] bytes = ramBytes[(int)((obj.DListOffset & 0xFF000000) >> 24)];

                            if (obj.DListOffset != 0x00 && bytes != null) //Need segment 6
                            {
                                //Load through the F3DEX parser, assign the DisplayListIndex to the Simple Object in the Reference DMA
                                //In the future we'll serialize the F3DEX commands/textures/vertices too, but for functional purposes
                                // we'll just use the blank binary
                                if (_referenceDMA.SimpleObjects[obj.ID].GLDisplayListOffset == F3DEXParser.InvalidBox)
                                    _referenceDMA.SimpleObjects[obj.ID].GLDisplayListOffset = _f3dex.ReadGameObject(level, bytes, obj.DListOffset); //KEEP AN EYE OUT FOR ANY CROSS-DMA REFERENCES
                            }
                        }
                    }
                    //We know that the 0x3E8 is the start of advanced objects
                    else if (obj.ID >= 0x3E8)
                    {
                        int scriptID = obj.ID - 0x3E8;

                        //Have to go digging around and creating the object scripts
                        int scriptStartOffset = StarFoxRomInfo.LevelIndexAndAdvItemIndex[levelIndices.IndexOf(DMATable.IndexOf(level))];

                        if (scriptStartOffset == 0)
                            continue;

                        SFAdvancedObjectScript script = level.LevelScripts.SingleOrDefault(s => s.ScriptIndex == scriptID);

                        if (script == null)
                        {
                            int scriptOffset = ByteHelper.ReadInt(levelBytes, scriptStartOffset + scriptID * 0x4);

                            int scriptOffsetShort = scriptOffset & 0x00FFFFFF;

                            int size = 0;
                            uint nextLine = 0x0;

                            do
                            {
                                nextLine = ByteHelper.ReadUInt(levelBytes, scriptOffsetShort + size);
                                size += 4;
                            } while (nextLine != 0xFE000000);

                            byte[] scriptBytes = new byte[size];
                            Array.Copy(levelBytes, scriptOffsetShort, scriptBytes, 0, size);

                            script = new SFAdvancedObjectScript(scriptOffset, scriptID, scriptBytes);

                            level.LevelScripts.Add(script);

                        }

                        obj.AdvancedScript = script;

                        if (script.AdvancedObjectIndex != -1 && script.AdvancedObjectIndex < _referenceDMA.AdvancedObjects.Count)
                        {
                            obj.DListOffset = _referenceDMA.AdvancedObjects[script.AdvancedObjectIndex].DListOffset;

                            // dlist offset sanity checks
                            if (((obj.DListOffset & 4) != 0x0) ||							// dlist offset not 4 byte aligned
                                ((obj.DListOffset & 0xFF000000) == 0x80000000) ||	// dlist offset lies in ram, leave it alone for now
                                ((obj.DListOffset & 0xFF000000) == 0x00000000))	// invalid dlist
                                obj.DListOffset = 0x00;

                            else
                            {
                                byte[] bytes = ramBytes[(int)((obj.DListOffset & 0xFF000000) >> 24)];

                                if (obj.DListOffset != 0x00 && bytes != null) //Need segment 6
                                {
                                    //Load through the F3DEX parser, assign the DisplayListIndex to the Simple Object in the Reference DMA
                                    //In the future we'll serialize the F3DEX commands/textures/vertices too, but for functional purposes
                                    // we'll just use the blank binary
                                    if (_referenceDMA.AdvancedObjects[script.AdvancedObjectIndex].GLDisplayListOffset == F3DEXParser.InvalidBox)
                                        _referenceDMA.AdvancedObjects[script.AdvancedObjectIndex].GLDisplayListOffset = _f3dex.ReadGameObject(level, bytes, obj.DListOffset); //KEEP AN EYE OUT FOR ANY CROSS-DMA REFERENCES
                                }
                            }
                        }
                    }
                }
            }

            _resourcesLoaded = true;
        }