示例#1
0
 public GscObject(RAMStream data)
 {
     Sprite            = data.u8();
     MapObjectIndex    = data.u8();
     SpriteTile        = data.u8();
     MovementType      = (GscSpriteMovement)data.u8();
     Flags             = data.u16be();
     Palette           = (GscPalette)data.u8();
     Walking           = data.u8();
     Direction         = data.u8();
     StepType          = data.u8();
     StepDuration      = data.u8();
     Action            = data.u8();
     ObjectStepFrame   = data.u8();
     Facing            = data.u8();
     StandingTile      = data.u8();
     LastTile          = data.u8();
     StandingMapX      = data.u8();
     StandingMapY      = data.u8();
     LastMapX          = data.u8();
     LastMapY          = data.u8();
     ObjectInitX       = data.u8();
     ObjectInitY       = data.u8();
     Radius            = data.u8();
     SpriteX           = data.u8();
     SpriteY           = data.u8();
     SpriteXOffset     = data.u8();
     SpriteYOffset     = data.u8();
     MovementByteIndex = data.u8();
     Field1c           = data.u8();
     Field1d           = data.u8();
     Field1e           = data.u8();
     Field1f           = data.u8();
     Range             = data.u8();
 }
示例#2
0
 public GscMapObject(RAMStream data)
 {
     StructID  = data.u8();
     Sprite    = data.u8();
     YCoord    = data.u8();
     XCOord    = data.u8();
     Movement  = data.u8();
     Raidus    = data.u8();
     Hour      = data.u8();
     TimeOfDay = data.u8();
     Color     = (GscPalette)data.u8();
     Range     = data.u8();
     Script    = data.u16le();
     EventFlag = data.u16le();
 }
示例#3
0
    public Bitmap Render(GscPalette timePalette)
    {
        byte[] tiles        = Tileset.GetTiles(Game.ROM.Subarray(Blocks, Width * Height), Width);
        byte[] decompressed = LZ.Decompress(Game.ROM.From(Tileset.GFX));

        byte[] gfx = new byte[0xe00];
        Array.Copy(decompressed, 0, gfx, 0, 0x600); // vram bank 1
        if (decompressed.Length > 0x600)
        {
            Array.Copy(decompressed, 0x600, gfx, 0x800, 0x600); // optional vram bank 2
        }

        if (Tileset.Id == 1 || Tileset.Id == 2 || Tileset.Id == 4)
        {
            // Load map group specific roof tiles.
            byte roofIndex = Game.ROM[Game.SYM["MapGroupRoofs"] + Group];
            if (roofIndex != 0xff)
            {
                Array.Copy(Game.ROM.Data, Game.SYM["Roofs"] + roofIndex * 0x90, gfx, 0xa0, 0x90);
            }
        }

        int timeOffset = 0;

        switch (timePalette)
        {
        case GscPalette.Morn: timeOffset = 0; break;

        case GscPalette.Auto:     // TODO: Don't always default to day time?
        case GscPalette.Day: timeOffset = 1; break;

        case GscPalette.Nite: timeOffset = 2; break;

        case GscPalette.Dark: timeOffset = 3; break;
        }

        byte palMapBank;

        if (Game.IsCrystal)
        {
            palMapBank = 0x13;
        }
        else
        {
            palMapBank = 0x02;
        }

        byte[] pixels = new byte[tiles.Length * 16];
        byte[] palMap = new byte[tiles.Length];

        for (int i = 0; i < tiles.Length; i++)
        {
            byte tile = tiles[i];
            Array.Copy(gfx, tile * 16, pixels, i * 16, 16);

            int  bankOffset = tile > 0x60 ? 0x20 : 0;
            byte palType    = Game.ROM[(palMapBank << 16 | Tileset.PalMap) + (tile + bankOffset) / 2];
            if ((tile & 1) == 0)
            {
                palType &= 0xf;
            }
            else
            {
                palType >>= 4;
            }

            palMap[i] = Game.ROM[EnvironmentColorPointer + timeOffset * 8 + palType];
        }

        ushort[] bgPalData   = Game.ROM.From("TilesetBGPalette").ReadLE(168);
        ushort[] roofPalData = Game.ROM.From(Game.SYM["RoofPals"] + Group * 8).ReadLE(4);
        Array.Copy(roofPalData, 0, bgPalData, 6 * 4 + 1, 2);
        Array.Copy(roofPalData, 0, bgPalData, 14 * 4 + 1, 2);
        Array.Copy(roofPalData, 2, bgPalData, 22 * 4 + 1, 2);

        byte[][][] bgPal = new byte[42][][];
        for (int i = 0; i < bgPal.Length; i++)
        {
            bgPal[i] = new byte[4][];
            for (int j = 0; j < 4; j++)
            {
                bgPal[i][j] = new byte[3];

                ushort val = bgPalData[i * 4 + j];
                bgPal[i][j][0] = (byte)(((val) & 0x1f) << 3);
                bgPal[i][j][1] = (byte)(((val >> 5) & 0x1f) << 3);
                bgPal[i][j][2] = (byte)(((val >> 10) & 0x1f) << 3);
            }
        }

        Bitmap bitmap = new Bitmap(Width * 2 * 2 * 8, Height * 2 * 2 * 8);

        bitmap.Unpack2BPP(pixels, bgPal, palMap);
        return(bitmap);
    }
示例#4
0
    public GscMap(Gsc game, int group, int number, ReadStream data)
    {
        Game   = game;
        Group  = (byte)group;
        Number = (byte)number;
        Id     = group << 8 | number;
        byte bank = data.u8();

        Tileset      = game.Tilesets[data.u8()];
        Environment  = data.u8();
        Attributes   = bank << 16 | data.u16le();
        Location     = data.u8();
        Music        = data.u8();
        PhoneService = data.Nybble() == 0;
        TimeOfDay    = (GscPalette)data.Nybble();
        FishGroup    = (GscFishGroup)data.u8();

        Name = game.SYM[Attributes];
        Name = Name.Substring(0, Name.IndexOf("_MapAttributes"));

        EnvironmentColorPointer = game.SYM["EnvironmentColorsPointers"] & 0xff0000 | game.ROM.u16le(game.SYM["EnvironmentColorsPointers"] + Environment * 2);

        ReadStream attributesData = game.ROM.From(Attributes);

        BorderBlock     = attributesData.u8();
        Height          = attributesData.u8();
        Width           = attributesData.u8();
        Blocks          = attributesData.u8() << 16 | attributesData.u16le();
        Scripts         = attributesData.u8() << 16 | attributesData.u16le();
        Events          = (Scripts & 0xff0000) | attributesData.u16le();
        ConnectionFlags = attributesData.u8();

        Connections = new GscConnection[4];
        for (int i = 3; i >= 0; i--)
        {
            if (((ConnectionFlags >> i) & 1) == 1)
            {
                Connections[i] = new GscConnection(this, attributesData);
            }
        }

        ReadStream eventsData = game.ROM.From(Events + 2);

        Warps = new DataList <GscWarp>();
        Warps.IndexCallback    = obj => obj.Index;
        Warps.PositionCallback = obj => (obj.X, obj.Y);
        byte numWarps = eventsData.u8();

        for (byte i = 0; i < numWarps; i++)
        {
            Warps.Add(new GscWarp(game, this, i, eventsData));
        }

        CoordEvents = new DataList <GscCoordEvent>();
        CoordEvents.PositionCallback = obj => (obj.X, obj.Y);
        byte numCoordEvents = eventsData.u8();

        for (byte i = 0; i < numCoordEvents; i++)
        {
            CoordEvents.Add(new GscCoordEvent(game, this, eventsData));
        }

        BGEvents = new DataList <GscBGEvent>();
        BGEvents.PositionCallback = obj => (obj.X, obj.Y);
        byte numBGEvents = eventsData.u8();

        for (byte i = 0; i < numBGEvents; i++)
        {
            BGEvents.Add(new GscBGEvent(game, this, eventsData));
        }

        Sprites = new DataList <GscSprite>();
        Sprites.IndexCallback    = obj => obj.Id;
        Sprites.PositionCallback = obj => (obj.X, obj.Y);
        byte numSprites = eventsData.u8();

        for (byte i = 0; i < numSprites; i++)
        {
            Sprites.Add(new GscSprite(game, this, i, eventsData));
        }

        byte[] blocks = game.ROM.Subarray(Blocks, Width * Height);
        Tiles = new GscTile[Width * 2, Height * 2];
        for (int i = 0; i < blocks.Length; i++)
        {
            byte block = blocks[i];
            for (int j = 0; j < 4; j++)
            {
                byte collision      = game.ROM[Tileset.Coll + block * 4 + j];
                int  tileSpaceIndex = i * 2 + (j & 1) + (j >> 1) * (Width * 2) + (i / Width * 2 * Width);
                byte xt             = (byte)(tileSpaceIndex % (Width * 2));
                byte yt             = (byte)(tileSpaceIndex / (Width * 2));
                Tiles[xt, yt] = new GscTile {
                    Map       = this,
                    X         = xt,
                    Y         = yt,
                    Collision = collision,
                };
            }
        }
    }