protected void SetNametableMirroring(MirroringMode mode) { switch (mode) { case MirroringMode.Horizontal: // Horizontal mirroring: A A // B B this.MapNametableA(0x2000); this.MirrorPpuRange(0x2000, 0x23FF, 0x2400, 0x27FF); this.MapNametableB(0x2800); this.MirrorPpuRange(0x2800, 0x2BFF, 0x2C00, 0x2FFF); break; case MirroringMode.Vertical: // Vertical mirroring: A B // A B this.MapNametableA(0x2000); this.MirrorPpuRange(0x2000, 0x23FF, 0x2800, 0x2BFF); this.MapNametableB(0x2400); this.MirrorPpuRange(0x2400, 0x27FF, 0x2C00, 0x2FFF); break; case MirroringMode.SingleScreenA: // One screen, mapped to lower nametable: A A // A A this.MapNametableA(0x2000); this.MapNametableB(-1); this.MirrorPpuRange(0x2000, 0x23FF, 0x2400, 0x2FFF); break; case MirroringMode.SingleScreenB: // One screen, mapped to upper nametable: B B // B B this.MapNametableA(-1); this.MapNametableB(0x2400); this.MirrorPpuRange(0x2400, 0x27FF, 0x2000, 0x23FF); this.MirrorPpuRange(0x2400, 0x27FF, 0x2800, 0x2FFF); break; default: throw new NotImplementedException(String.Format(CultureInfo.CurrentCulture, "Nametable mirroring mode '{0}' is not implemented!", mode)); } }
private void LoadRom(string path) { byte[] rawROM = File.ReadAllBytes(path); byte[] header = new ArraySegment <byte>(rawROM, 0, 16).ToArray(); byte[] signature = new ArraySegment <byte>(header, 0, 3).ToArray(); if (Encoding.ASCII.GetString(signature) != "NES") { throw new NotImplementedException("Only ROMS with iNES headers supported."); } PRGROM16K = header[4]; CHRROM8K = header[5]; PRGROM8K = header[8]; int flag6 = header[6]; int flag7 = header[7]; int flag9 = header[9]; int flag10 = header[10]; mirroringMode = (flag6 & 1) == 1 ? MirroringMode.Vertical : MirroringMode.Horizontal; Trainer = (flag6 & 4) != 0; NTSC = (flag10 & 1) == 0; Mapper = flag6 >> 4 | (flag7 & 0xf0); //Lower nibble of flag6 | upper nibble of flag7 int prgFrom = 16; if (Trainer) { prgFrom += 512; } int prgLength = 0x4000 * PRGROM16K; PRGData = new ArraySegment <Byte>(rawROM, prgFrom, prgLength).ToArray(); int chrFrom = prgFrom + prgLength; int chrLength = 0x2000 * CHRROM8K; CHRData = new ArraySegment <Byte>(rawROM, chrFrom, chrLength).ToArray(); }
private void ReadHeader(ref SpanReader span) { if (span.ReadAsUnsignedInt() != _magicNumber) { throw new InvalidDataException("Invalid nes file."); } PrgRomSize = span.ReadAsByte() * 16u * 1024; ChrRomSize = span.ReadAsByte() * 8u * 1024; var flag6 = span.ReadAsByte(); MirroringMode = (MirroringMode)(flag6 & 0b1); HasTrainer = (flag6 & 0b001) != 0; var flag7 = span.ReadAsByte(); PrgRamSize = Math.Max((byte)1, span.ReadAsByte()) * 8u * 1024; var flag9 = span.ReadAsByte(); var flag10 = span.ReadAsByte(); span.Advance(5); }
public void SetMirroringMode(MirroringMode mirroringMode) { _mirroringMode = mirroringMode; PlayerPrefs.SetInt("mirroringMode", (int)_mirroringMode); if (_mirroringMode == MirroringMode.None) { _editor.MirroringString = ""; } else if (_mirroringMode == MirroringMode.Horizontal) { _editor.MirroringString = "-MIRROR HORZ-"; } else if (_mirroringMode == MirroringMode.Vertical) { _editor.MirroringString = "|MIRROR VERT|"; } else if (_mirroringMode == MirroringMode.Both) { _editor.MirroringString = "/MIRROR BOTH/"; } }
public void SetMirroringMode(MirroringMode mirroringMode) { _mirroringMode = mirroringMode; PlayerPrefs.SetInt("mirroringMode", (int)_mirroringMode); if(_mirroringMode == MirroringMode.None) _editor.MirroringString = ""; else if(_mirroringMode == MirroringMode.Horizontal) _editor.MirroringString = "-MIRROR HORZ-"; else if(_mirroringMode == MirroringMode.Vertical) _editor.MirroringString = "|MIRROR VERT|"; else if(_mirroringMode == MirroringMode.Both) _editor.MirroringString = "/MIRROR BOTH/"; }
public INESFile Parse(byte[] bytes) { this.Header = new ArraySegment <byte>(bytes, 0, 16); // Expecting NES<eof> at the start of the file. var fileIdentifier = BitConverter.ToUInt32(this.Header.Array, 0); if (fileIdentifier != Constants.FileSignature) { throw new InvalidOperationException("File does not have expected header for iNES file."); } this.ProgramROMBankCount = this.Header.Get(4); this.CharacterROMBankCount = this.Header.Get(5); this.RAMBankCount = this.Header.Get(8); if (this.RAMBankCount == 0) { this.RAMBankCount = 1; } this.RomControlByte1 = this.Header.Get(6); this.RomControlByte2 = this.Header.Get(7); this.MapperTypeLowerBits = (byte)(this.RomControlByte1 & 0xff0); this.MapperTypeUpperBits = (byte)(this.RomControlByte2 & 0xff0); // We pull the memory mapper id from the two separate bytes above and combine them here... this.MemoryMapperId = (MemoryMapperIds)(this.MapperTypeUpperBits | this.MapperTypeLowerBits >> 4); this.MirroringMode = this.RomControlByte1.GetBit(0) ? MirroringMode.Vertical : MirroringMode.Horizontal; // The mirroring mode can be overridden a couple bits later... this.MirroringMode = this.RomControlByte1.GetBit(3) ? MirroringMode.FourScreen : this.MirroringMode; for (int i = 0; i < 7; i++) { this.Reserved[i] = this.Header.Get(9 + i); } if (this.HasTrainer) { this.Trainer = new ArraySegment <byte>(bytes, Constants.LocationOfTrainer, Constants.SizeOfTrainer).ToArray(); } if (this.HasBatteryBackedRAM) { // TODO: We'll want to load in a file here at a later time this.SRAM = new ArraySegment <byte>(bytes, Constants.LocationOfSRAM, Constants.SizeOfSRAM).ToArray(); } else { this.SRAM = new byte[Constants.SizeOfSRAM]; } int romBankOffset = this.HasTrainer ? Constants.SizeOfHeader + Constants.SizeOfTrainer : Constants.SizeOfHeader; for (int i = 0; i < this.ProgramROMBankCount; i++) { this.ROMBanks.Add(new ArraySegment <byte>(bytes, romBankOffset + (i * Constants.ROMBankSize), Constants.ROMBankSize).ToArray()); } int chrBankOffset = romBankOffset + this.ROMBanks.Sum(bank => bank.Length); for (int i = 0; i < this.CharacterROMBankCount; i++) { this.CharacterBanks.Add(new ArraySegment <byte>(bytes, chrBankOffset + (i * Constants.ChrBankSize), Constants.ChrBankSize).ToArray()); } return(this); }