public Nametable(ChrMapper mapper) { this.bitmap = new PaletteBitmap(screenWidth * 8u, screenHeight * 8u); this.mapper = mapper; this.ppuAddr = 0x0000; this.SetDirection(AccessDirection.Horizontal); bitmap.AddColor(0x00000000); // Transparent }
private void GenerateTile(PaletteBitmap bitmap, ChrMapper mapper, uint row, uint col, byte tile) { for (uint tileY = 0; tileY < 8; tileY++) { uint drawY = (uint)(row * 8 + tileY); for (uint tileX = 0; tileX < 8; tileX++) { uint drawX = col * 8 + tileX; byte color = mapper.GetPixel(tile, tileX, tileY); bitmap.SetPixel(drawX, drawY, (byte)(color + 1)); } } }
private IVisualization2d GenerateBitmap(ReadOnlyDictionary <string, object> parms) { int tileoffset = Util.GetFromObjDict(parms, P_TILEOFFSET, 0); int width = Util.GetFromObjDict(parms, P_WIDTH, 1); int height = Util.GetFromObjDict(parms, P_HEIGHT, 1); int chroffset = Util.GetFromObjDict(parms, P_CHROFFSET, 0); int chipoffset = Util.GetFromObjDict(parms, P_CHIPOFFSET, 0); int chrbank1 = Util.GetFromObjDict(parms, P_CHRBANK1, 0); int chrbank2 = Util.GetFromObjDict(parms, P_CHRBANK2, 1); int chrbank3 = Util.GetFromObjDict(parms, P_CHRBANK3, 2); int chrbank4 = Util.GetFromObjDict(parms, P_CHRBANK4, 3); int palette1 = Util.GetFromObjDict(parms, P_PALETTE1, 0x0F); int palette2 = Util.GetFromObjDict(parms, P_PALETTE2, 0x00); int palette3 = Util.GetFromObjDict(parms, P_PALETTE3, 0x10); int palette4 = Util.GetFromObjDict(parms, P_PALETTE4, 0x30); bool vertical = Util.GetFromObjDict(parms, P_VERTICAL, false); int[] bank = new int[4] { chrbank1, chrbank2, chrbank3, chrbank4 }; int[] palette = new int[4] { palette1, palette2, palette3, palette4 }; ChrMapper mapper = null; // Check parameters. try{ { // tile int lastAddress = tileoffset + width * height - 1; if ((tileoffset < 0) || (lastAddress >= this.mFileData.Length)) { this.mAppRef.ReportError("Invalid parameter"); return(null); } } { // bank int lastAddress = chroffset + 0x03FF; // chr = [0, 0, 0, 0] -> 0x1000 / 4 - 1 = 0x03FF if ((chroffset < 0) || (lastAddress >= this.mFileData.Length)) { this.mAppRef.ReportError("Invalid parameter"); return(null); } } // palette for (int i = 0; i < palette.Length; i++) { int color = palette[i]; if (color >= NesPalette.Length) { this.mAppRef.ReportError("Invalid parameter"); return(null); } } // Copy CHR data. mapper = new ChrMapper(this.mFileData, chroffset, bank); } catch { this.mAppRef.ReportError("Invalid parameter"); return(null); } // Set palette. PaletteBitmap bitmap = new PaletteBitmap((uint)(width * 8), (uint)(height * 8)); bitmap.AddColor(0x00000000); // Transparent for (int i = 0; i < palette.Length; i++) { int index = palette[i]; if (index >= 0) { UInt32 color = 0xFF000000U | (UInt32)NesPalette[index]; bitmap.AddColor((int)color); // ARGB } else { bitmap.AddColor(0x00000000); // Transparent } } // Convert to pixels. for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { int address; if (!vertical) { // Horizontal address = tileoffset + (row * width) + col; } else { // Vertical address = tileoffset + (col * height) + row; } byte tile = (byte)(this.mFileData[address] + chipoffset); this.GenerateTile(bitmap, mapper, (uint)row, (uint)col, tile); } } return(bitmap.Bitmap); }
private IVisualization2d GenerateBitmap(ReadOnlyDictionary <string, object> parms) { int tileoffset = Util.GetFromObjDict(parms, P_DATAOFFSET, 0); int chroffset = Util.GetFromObjDict(parms, P_CHROFFSET, 0); int chrbank1 = Util.GetFromObjDict(parms, P_CHRBANK1, 0); int chrbank2 = Util.GetFromObjDict(parms, P_CHRBANK2, 1); int chrbank3 = Util.GetFromObjDict(parms, P_CHRBANK3, 2); int chrbank4 = Util.GetFromObjDict(parms, P_CHRBANK4, 3); int palette1 = Util.GetFromObjDict(parms, P_PALETTE1, 0x0F); int palette2 = Util.GetFromObjDict(parms, P_PALETTE2, 0x00); int palette3 = Util.GetFromObjDict(parms, P_PALETTE3, 0x10); int palette4 = Util.GetFromObjDict(parms, P_PALETTE4, 0x30); int[] bank = new int[4] { chrbank1, chrbank2, chrbank3, chrbank4 }; int[] palette = new int[4] { palette1, palette2, palette3, palette4 }; ChrMapper mapper = null; // Check parameters. try{ { // bank int lastAddress = chroffset + 0x03FF; // chr = [0, 0, 0, 0] -> 0x1000 / 4 - 1 = 0x03FF if ((chroffset < 0) || (lastAddress >= this.mFileData.Length)) { this.mAppRef.ReportError("Invalid parameter"); return(null); } } // palette for (int i = 0; i < palette.Length; i++) { int color = palette[i]; if (color >= Nes.Palette.Length) { this.mAppRef.ReportError("Invalid parameter"); return(null); } } // Copy CHR data. mapper = new ChrMapper(this.mFileData, chroffset, bank); } catch { this.mAppRef.ReportError("Invalid parameter"); return(null); } // Create virtual nametable. Nametable nametable = new Nametable(mapper); // Set palette. for (int i = 0; i < palette.Length; i++) { nametable.AddColor(palette[i]); } // Convert to pixels. try{ int index = tileoffset; while (true) { byte addrHigh = this.mFileData[index++]; if ((addrHigh == 0x00) || (addrHigh >= 0x80)) // Invalid address { break; } byte addrLow = this.mFileData[index++]; byte length = this.mFileData[index++]; bool isVertical = (length & 0x80) != 0; bool isSolid = (length & 0x40) != 0; int writeLength = (length & 0x3F); int addr = (addrHigh << 8) | addrLow; Nametable.AccessDirection direction = (isVertical)? Nametable.AccessDirection.Vertical : Nametable.AccessDirection.Horizontal; nametable.SetAddress((UInt16)addr); nametable.SetDirection(direction); if (!isSolid) { for (int i = 0; i < writeLength; i++) { byte value = this.mFileData[index++]; nametable.Write(value); } } else { byte value = this.mFileData[index++]; for (int i = 0; i < writeLength; i++) { nametable.Write(value); } } } } catch { this.mAppRef.ReportError("Invalid parameter"); return(null); } return(nametable.Bitmap); }