/* * /// <summary> * /// Get a color map bitmap * /// </summary> * public Bitmap this[byte index] * { * get * { * return this.getColorMapBmp(index); * } * }*/ #endregion #region Methods /// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() == (COLORMAP_DATA_SIZE)) { if ((!this.isReady) && (this._buffer != null) && (this._palette.isReady)) { //build colormap in memory, per color for (ushort colMap = 0; colMap < COLORMAP_COUNT; colMap++) { for (byte i = 0; i < COLORMAP_SIZE; i++) { this._colorMaps[colMap, i] = this._rawData[colMap * 0xFF + i]; } } /* * for (int i = 0; i < COLORMAP_SIZE; i += 3) * { * for (ushort colMap = 0; colMap < COLORMAP_COUNT; colMap++) * { * int indexToProcess = 3 * i; //get 3 bytes for 3 color values (RGB) * * this._colorMaps[colMap, i] = this._rawData[indexToProcess]; * this._colorMaps[colMap, i +1] = this._rawData[indexToProcess + 1]; * this._colorMaps[colMap, i +2] = this._rawData[indexToProcess + 2]; * } * * } */ //build buffer bitmap (just for output to user) using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { for (ushort palIndex = 0; palIndex < COLORMAP_COUNT; palIndex++) { for (ushort colOfs = 0; colOfs < COLORMAP_SIZE; colOfs++) { byte iPaletteColorIndex = this._colorMaps[palIndex, colOfs]; //read a pixel value Color rott2dImgColor = this._palette[iPaletteColorIndex]; //convert to Color fastBuffer.SetColor(colOfs, palIndex, rott2dImgColor); } } } //flag ready this.ForceIsReady(); } } }
/// <summary> /// clear buffer (parameter by value!) /// </summary> public void FillBuffer(int width, int height, ref Color color) { if (this._buffer != null) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { //set all pixels to transparent color (index 255) for (int y = 0; y < width; y++) { for (int x = 0; x < height; x++) { fastBuffer.SetColor(x, y, color); //this._buffer.SetPixel(x, y, color); } } } } }
/// <summary> /// return the selected colormap data /// </summary> public Bitmap GetColorMapBmp(byte palIndex) { Bitmap colormapBmp = new Bitmap(COLORMAP_SIZE, 1, PixelFormat.Format24bppRgb); if ((this.isReady) && (this._colorMaps != null)) { if (this._colorMaps.Length > 0) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { for (ushort colOfs = 0; colOfs < COLORMAP_SIZE; colOfs++) { byte iPaletteColorIndex = this._colorMaps[palIndex, colOfs]; //read a pixel value Color rott2dImgColor = this._palette[iPaletteColorIndex]; //convert to Color fastBuffer.SetColor(colOfs, 0, rott2dImgColor); } } //using fastBuffer } //length check } //is ready return(colormapBmp); }
/// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() >= RAW_MINIMAL_DATA_SIZE) { if ((this._buffer != null) && (this._palette.isReady)) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { int iLumpIndex = 0; //index for lump data array to byte (wall 0-4096, sky 0-512000) ushort iPaletteColorIndex = 0; //return value for lump palette color index (0-256) //generate pixels in bitmap, starting with Y value (for ROTT's "modex" compatibility mode) for (int y = 0; y < this.TextureHeight; y++) { for (int x = 0; x < this.TextureWidth; x++) { //convert lump data to Palette Index values iPaletteColorIndex = this._rawData[iLumpIndex++]; //get Palette Index and create color value Color rott2dImgColor = this._palette[iPaletteColorIndex]; //rott2dImgColor = Color.FromArgb(colormap[iPaletteColorIndex].a, colormap[iPaletteColorIndex].r, colormap[iPaletteColorIndex].g, colormap[iPaletteColorIndex].b); //draw color pixels to bitmap texture fastBuffer.SetColor(x, y, rott2dImgColor); //this._buffer.SetPixel(x, y, rott2dImgColor); } } } //rotate bitmap 90 degrees this.RotateBuffer(); //flag ready this.ForceIsReady(); } } }
/// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() >= Rott2DPatchHeader.PATCH_HEADER_SIZE) { if ((this.isHeaderReady) && (this._buffer != null) && (this._palette.isReady)) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { //generate pixels to bitmap int iLumpIndex = Rott2DPatchHeader.PATCH_HEADER_SIZE; //start pixels processing from last header byte ushort iPaletteColorIndex = 0; //return value for lump palette color index (0-256) //generate pixels in bitmap for (int x = 0; x < this._patchHeader.PatchWidth; x++) { for (int y = 0; y < this._patchHeader.PatchHeight; y++) { //convert lump data to Palette Index values iPaletteColorIndex = this._rawData[iLumpIndex++]; //get Palette Index and create color value Color rott2dImgColor = this._palette[iPaletteColorIndex]; //draw color pixels to bitmap texture fastBuffer.SetColor(x, y, rott2dImgColor); //this._buffer.SetPixel(x, y, rott2dImgColor); } } } //flag ready this.ForceIsReady(); } } }
/// <summary> /// DEBUGGING STUFF, TO BE REMOVED FROM SOURCE /// </summary> /*private void DumpRawStreamToPic() * { * if (this.isHeaderReady) * { * using (Bitmap dumper = new Bitmap(this._rawData.Length, 1)) * { * for (int p = 0; p < this._rawData.Length; p++) * { * short index = this._rawData[p]; * * Color colorDump = this._palette[index]; * * dumper.SetPixel(p, 0, colorDump); * } * * dumper.Save(Environment.CurrentDirectory + @"\data\cache\dump.bmp"); * } * } * }*/ /// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() > Rott2DPicHeader.PIC_HEADER_SIZE) { if ((this.isHeaderReady) && (this._buffer != null) && (this._palette.isReady)) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { //first, fill buffer with transparency color from palette Color textureTransparencyColor = this._palette.GetMaskedColor(); fastBuffer.SetFill(textureTransparencyColor); //this.fillBuffer(ref textureTransparencyColor); //convert pic_t raw data stream to Bitmap int iLumpIndex = Rott2DPicHeader.PIC_HEADER_SIZE; //start pixels processing from last header byte ushort iPaletteColorIndex = Rott2DPalette.DEFAULT_MASKED_COLOR; //value for lump palette color index (0-255) int iLastLumpIndex = iLumpIndex; //remeber last LumpIndex start offset int iColoffFactor = 1; //set starting factor not zero. //go for all pic_t columns //(this is a modex image format) for (ushort x = 0; x < this._picHeader.PicWidth; x++) //rows (horz) { //After the first three rows, start checking if we have a col off's //that is dividable by four. If so, shift index by one in the raw data //bytes stream and start reading from that position on. //For images of 16 pix width, this happens once. Larger width then 16 results in more shifts. if (x > (Rott2DPicHeader.PIC_HEADER_MULTIPLIER - 1)) //x > 3 { iColoffFactor = x % Rott2DPicHeader.PIC_HEADER_MULTIPLIER; //x % 4 if (iColoffFactor == 0) { iLumpIndex = iLastLumpIndex = iLastLumpIndex + 1; } } //go down the pic_t colums and read pixels for (ushort y = 0; y < this._picHeader.PicHeight; y++) //cols (vert) { //get color and decide if is transparent color or not iPaletteColorIndex = this._rawData[iLumpIndex]; //get color from palette if (iPaletteColorIndex != 255) { //draw palette color Color rott2dImgColor = this._palette[iPaletteColorIndex]; fastBuffer.SetColor(x, y, rott2dImgColor); //this._buffer.SetPixel(x, y, rott2dImgColor); } iLumpIndex += this._picHeader.PicPlaneSize; //move ahead in the data stream by supplied multiplier } } } //flag ready this.ForceIsReady(); } } }
/// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() == (this._dataSize + Rott2DMaskedHeader.MASKED_HEADER_SIZE)) { if ((this.isHeaderReady) && (this._buffer != null) && (this._palette.isReady)) { using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { //generate pixels to bitmap ushort iPaletteColorIndex = 0; //return value for lump palette color index (0-256) //read column offset pointers int pos = Rott2DMaskedHeader.MASKED_HEADER_SIZE; for (int col = 0; col < this._maskedHeader.Width; col++) { this._maskedHeader[col] = BitConverter.ToUInt16(this._rawData, pos); //store pointer position in colofs pos += sizeof(ushort); //move two bytes further } //first, fill buffer with default transparency color from palette Color textureTransparencyColor = this._palette.GetMaskedColor(); fastBuffer.SetFill(textureTransparencyColor); //this.fillBuffer(ref textureTransparencyColor); //generate pixels in bitmap for (ushort iXpos = 0; iXpos < this._maskedHeader.Width; iXpos++) { Rott2DMaskedPost postData = new Rott2DMaskedPost(); //create post data postData.Offset = this._maskedHeader[iXpos]; //get post data Offset ushort iYpos = this._rawData[postData.Offset]; //read first position in row while (iYpos != Rott2DMaskedPost.MASKED_POST_TERMINATOR) //continue until row is terminated { postData.NumberOfPixels = this._rawData[postData.getNextOffset()]; //read number of pixels in post if (iYpos + postData.NumberOfPixels > this._maskedHeader.Height) { break; //skip is we reached Height of bitmap! } //read a full post (= row of pixels to be drawn) for (byte iPost = 0; iPost < postData.NumberOfPixels; iPost++) { iPaletteColorIndex = this._rawData[postData.getNextOffset()]; //read a pixel value Color rott2dImgColor = this._palette[iPaletteColorIndex]; //convert to Color fastBuffer.SetColor(iXpos, iYpos + iPost, rott2dImgColor); //this._buffer.SetPixel(iXpos, iYpos + iPost, rott2dImgColor); //draw } iYpos = this._rawData[postData.getNextOffset()]; //goto next row offset } } } //flag ready this.ForceIsReady(); } } }
/// <summary> /// Generate the buffer texture /// </summary> protected override void ProcessLumpData() { if (this.GetDataSize() == (this._dataSize + Rott2DTransMaskedHeader.TRANSMASKED_HEADER_SIZE)) { if ((this.isHeaderReady) && (this._buffer != null) && (this._palette.isReady)) { //generate pixels to bitmap using (Rott2DFastBitmap fastBuffer = new Rott2DFastBitmap(this._buffer)) { ushort iPaletteColorIndex = 0; //return value for lump palette color index (0-256) //read column offset pointers int pos = Rott2DTransMaskedHeader.TRANSMASKED_HEADER_SIZE; for (int col = 0; col < this._transMaskedHeader.Width; col++) { this._transMaskedHeader[col] = BitConverter.ToUInt16(this._rawData, pos); //store pointer position in colofs pos += sizeof(ushort); //move two bytes further } //first, fill buffer with default transparency color from palette //Color textureTransparencyColor = this._palette[Rott2DPalette.PALETTE_TRANSPARENT_COLOR]; Color textureTransparencyColor = this._palette.GetMaskedColor(); fastBuffer.SetFill(textureTransparencyColor); //this.fillBuffer(this._transMaskedHeader.Width, this._transMaskedHeader.Height, textureTransparencyColor); //generate pixels in bitmap for (ushort iXpos = 0; iXpos < this._transMaskedHeader.Width; iXpos++) { Rott2DTransMaskedPost postData = new Rott2DTransMaskedPost(); //create a post header data postData.Offset = this._transMaskedHeader[iXpos]; //get post data Offset ushort iYpos = (ushort)this._rawData[postData.Offset]; //read first position in row byte transbyte = 0; //this is our "special" post pre-reading byte value while (iYpos != Rott2DTransMaskedPost.TRANSMASKED_POST_TERMINATOR) //continue until row is terminated { postData.NumberOfPixels = this._rawData[postData.GetNextOffset()]; //read number of pixels in post if (iYpos + postData.NumberOfPixels > this._transMaskedHeader.Height) { break; //skip is we reached Height of bitmap! } //read first post byte if number of pixels is larger then zero //we need to do this check, or we go out of limits of the stream (SOLVED 06-02-2012). if (postData.NumberOfPixels > 0) { transbyte = this._rawData[postData.GetNextOffset()]; } //optimized routine for speed (less if-then-else checking) Color rott2dImgColor = this._palette.GetMaskedColor(); //default masked color from palette //get byte value, draw correct color if not transparent if (transbyte != Rott2DTransMaskedPost.TRANSMASKED_POST_SPECIAL) { //we have a regular post (such as in a masked texture), draw it! for (byte iPost = 0; iPost < postData.NumberOfPixels; iPost++) { //transbyte pre-reads a value that can be 254 (= TRANSMASKED_POST_SPECIAL). //this is the same as the first post byte value. //in other words: if iPost is zero, copy the transbyte value. iPaletteColorIndex = (iPost == 0) ? transbyte : this._rawData[postData.GetNextOffset()]; rott2dImgColor = this._palette[iPaletteColorIndex]; //convert to Color fastBuffer.SetColor(iXpos, iYpos + iPost, rott2dImgColor); //this._buffer.SetPixel(iXpos, iYpos + iPost, rott2dImgColor); //draw } } else { /* special post, * draw cracked/remaining glass pieces on the edges of the transmasked pictures * * notes: * in ROTT this is calculated with an ALPHA value for transparency * most of this can be found in rt_scale.c * int alpha = (((translevel+64)>>2)<<8) * * in WinRottGL this is calculated as (thanks to Birger): * int mask = (63 - translevel) << (ALPHA_SHIFT+2) * */ for (byte iPost = 0; iPost < postData.NumberOfPixels; iPost++) { iPaletteColorIndex = 32; //set dark value rott2dImgColor = this._palette[iPaletteColorIndex]; //convert to Color fastBuffer.SetColor(iXpos, iYpos + iPost, rott2dImgColor); //this._buffer.SetPixel(iXpos, iYpos + iPost, rott2dImgColor); //draw } } //finally, goto next row offset iYpos = this._rawData[postData.GetNextOffset()]; } } } //flag ready this.ForceIsReady(); } } }