ibuf16.cc

Go to the documentation of this file.
00001 /*
00002  *  ibuf16.cc - 16-bit image buffer.
00003  *
00004  *  Copyright (C) 1998-1999  Jeffrey S. Freedman
00005  *  Copyright (C) 2000-2001  The Exult Team
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #  include <config.h>
00024 #endif
00025 
00026 #include "ibuf16.h"
00027 #ifndef ALPHA_LINUX_CXX
00028 #  include <cstring>
00029 #  include <cstdlib>
00030 #endif
00031 
00032 #ifndef UNDER_CE
00033 using std::memmove;
00034 #endif
00035 
00036 /*
00037  *  Create a default palette for 8-bit graphics on a 16-bit display.
00038  */
00039 
00040 void Image_buffer16::create_default_palette
00041   (
00042   )
00043   {
00044   delete palette;     // Delete old.
00045   palette = new unsigned short[256];
00046   for (int i = 0; i < 256; i++)
00047     palette[i] = rgb(4*((i >> 5) & 0x7), 
00048       4*((i >> 2) & 0x7), 9*(i & 0x3));
00049   }
00050 
00051 /*
00052  *  Fill with a given 16-bit value.
00053  */
00054 
00055 void Image_buffer16::fill16
00056   (
00057   unsigned short pix
00058   )
00059   {
00060   unsigned short *pixels = get_pixels();
00061   int cnt = line_width*height;
00062   for (int i = 0; i < cnt; i++)
00063     *pixels++ = pix;
00064   }
00065 
00066 /*
00067  *  Fill a rectangle with a 16-bit value.
00068  */
00069 
00070 void Image_buffer16::fill16
00071   (
00072   unsigned short pix,
00073   int srcw, int srch,
00074   int destx, int desty
00075   )
00076   {
00077   int srcx = 0, srcy = 0;
00078           // Constrain to window's space.
00079   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00080     return;
00081   unsigned short *pixels = get_pixels() + desty*line_width + destx;
00082   int to_next = line_width - srcw;// # pixels to next line.
00083   while (srch--)      // Do each line.
00084     {
00085     for (int cnt = srcw; cnt; cnt--)
00086       *pixels++ = pix;
00087     pixels += to_next;  // Get to start of next line.
00088     }
00089   }
00090 
00091 /*
00092  *  Fill a line with a given 16-bit value.
00093  */
00094 
00095 void Image_buffer16::fill_line16
00096   (
00097   unsigned short pix,
00098   int srcw,
00099   int destx, int desty
00100   )
00101   {
00102   int srcx = 0, srcy = 0, srch = 1;
00103           // Constrain to window's space.
00104   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00105     return;
00106   unsigned short *pixels = get_pixels() + desty*line_width + destx;
00107   for (int cnt = srcw; cnt; cnt--)
00108     *pixels++ = pix;
00109   }
00110 
00111 /*
00112  *  Copy another rectangle into this one.
00113  */
00114 
00115 void Image_buffer16::copy16
00116   (
00117   unsigned short *src_pixels, // Source rectangle pixels.
00118   int srcw, int srch,   // Dimensions of source.
00119   int destx, int desty
00120   )
00121   {
00122   int srcx = 0, srcy = 0;
00123   int src_width = srcw;   // Save full source width.
00124           // Constrain to window's space.
00125   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00126     return;
00127   unsigned short *to = get_pixels() + desty*line_width + destx;
00128   unsigned short *from = src_pixels + srcy*src_width + srcx;
00129   int to_next = line_width - srcw;// # pixels to next line.
00130   int from_next = src_width - srcw;
00131   while (srch--)      // Do each line.
00132     {
00133     for (int cnt = srcw; cnt; cnt--)
00134       *to++ = *from++;
00135     to += to_next;
00136     from += from_next;
00137     }
00138   }
00139 
00140 /*
00141  *  Copy an area of the image within itself.
00142  */
00143 
00144 void Image_buffer16::copy
00145   (
00146   int srcx, int srcy,   // Where to start.
00147   int srcw, int srch,   // Dimensions to copy.
00148   int destx, int desty    // Where to copy to.
00149   )
00150   {
00151   int ynext, yfrom, yto;    // Figure y stuff.
00152   if (srcy >= desty)    // Moving up?
00153     {
00154     ynext = line_width;
00155     yfrom = srcy;
00156     yto = desty;
00157     }
00158   else        // Moving down.
00159     {
00160     ynext = -line_width;
00161     yfrom = srcy + srch - 1;
00162     yto = desty + srch - 1;
00163     }
00164   unsigned short *to = get_pixels() + yto*line_width + destx;
00165   unsigned short *from = get_pixels() + yfrom*line_width + srcx;
00166           // Go through lines.
00167   while (srch--)
00168     {
00169     memmove((char *) to, (char *) from, srcw * 2);
00170     to += ynext;
00171     from += ynext;
00172     }
00173   }
00174 
00175 /*
00176  *  Get a rectangle from here into another Image_buffer.
00177  */
00178 
00179 void Image_buffer16::get
00180   (
00181   Image_buffer *dest,   // Copy to here.
00182   int srcx, int srcy    // Upper-left corner of source rect.
00183   )
00184   {
00185   int srcw = dest->get_width(), srch = dest->get_height();
00186   int destx = 0, desty = 0;
00187           // Constrain to window's space. (Note
00188           //   convoluted use of clip().)
00189   if (!clip(destx, desty, srcw, srch, srcx, srcy))
00190     return;
00191   unsigned short *to = (unsigned short *) dest->bits + 
00192         desty*dest->line_width + destx;
00193   unsigned short *from = get_pixels() + srcy*line_width + srcx;
00194           // Figure # pixels to next line.
00195   int to_next = dest->line_width - srcw;
00196   int from_next = line_width - srcw;
00197   while (srch--)      // Do each line.
00198     {
00199     for (int cnt = srcw; cnt; cnt--)
00200       *to++ = *from++;
00201     to += to_next;
00202     from += from_next;
00203     }
00204   }
00205 
00206 /*
00207  *  Retrieve data from another buffer.
00208  */
00209 
00210 void Image_buffer16::put
00211   (
00212   Image_buffer *src,    // Copy from here.
00213   int destx, int desty    // Copy to here.
00214   )
00215   {
00216   Image_buffer16::copy16((unsigned short *) src->bits,
00217     src->get_width(), src->get_height(), destx, desty);
00218   }
00219 
00220 /*
00221  * Fill buffer with random static
00222  */
00223 void Image_buffer16::fill_static(int black, int gray, int white)
00224 {
00225   unsigned short *p = get_pixels();
00226   unsigned short black16 = palette[black];
00227   unsigned short gray16 = palette[gray];
00228   unsigned short white16 = palette[white];
00229   for (int i = width*height; i > 0; --i) {
00230     switch (std::rand()%5) {
00231       case 0: case 1: *p++ = black16; break;
00232       case 2: case 3: *p++ = gray16; break;
00233       case 4: *p++ = white16; break;
00234     }
00235   }
00236 }
00237 
00238 /*
00239  *  Convert rgb value.
00240  */
00241 
00242 inline unsigned char Get_color16
00243   (
00244   unsigned char val,
00245   int maxval,
00246   int brightness      // 100=normal.
00247   )
00248   {
00249   unsigned int c = (((unsigned int) val)*brightness*32)/
00250               (100*(maxval + 1));
00251   return (c < 32 ? c : 31);
00252   }
00253 
00254 /*
00255  *  Set palette.
00256  */
00257 
00258 void Image_buffer16::set_palette
00259   (
00260   unsigned char *rgbs,    // 256 3-byte entries.
00261   int maxval,     // Highest val. for each color.
00262   int brightness      // Brightness control (100 = normal).
00263   )
00264   {
00265           // Get the colors.
00266   for (int i = 0; i < 3*256; i += 3)
00267     {
00268     unsigned char r = Get_color16(rgbs[i], maxval, brightness);
00269     unsigned char g = Get_color16(rgbs[i + 1], maxval, brightness);
00270     unsigned char b = Get_color16(rgbs[i + 2], maxval, brightness);
00271     set_palette_color(i/3, r, g, b);
00272     }
00273   }
00274 
00275 /*
00276  *  Rotate a range of colors.
00277  */
00278 
00279 void Image_buffer16::rotate_colors
00280   (
00281   int first,      // Palette index of 1st.
00282   int num,      // # in range.
00283   int upd       // 1 to update hardware now.
00284   )
00285   {
00286   int cnt = num - 1;    // Shift downward.
00287   int c0 = palette[first];
00288   for (int i = first; cnt; i++, cnt--)
00289     palette[i] = palette[i + 1];
00290   palette[first + num - 1] = c0;  // Shift 1st to end.
00291           // +++++upd?
00292   }
00293 
00294 /*
00295  *  Copy another rectangle into this one.
00296  */
00297 
00298 void Image_buffer16::copy8
00299   (
00300   unsigned char *src_pixels,  // Source rectangle pixels.
00301   int srcw, int srch,   // Dimensions of source.
00302   int destx, int desty
00303   )
00304   {
00305   int srcx = 0, srcy = 0;
00306   int src_width = srcw;   // Save full source width.
00307           // Constrain to window's space.
00308   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00309     return;
00310   unsigned short *to = get_pixels() + desty*line_width + destx;
00311   unsigned char *from = src_pixels + srcy*src_width + srcx;
00312   int to_next = line_width - srcw;// # pixels to next line.
00313   int from_next = src_width - srcw;
00314   while (srch--)      // Do each line.
00315     {
00316     for (int cnt = srcw; cnt; cnt--)
00317       *to++ = palette[*from++];
00318     to += to_next;
00319     from += from_next;
00320     }
00321   }
00322 
00323 /*
00324  *  Copy a line into this buffer.
00325  */
00326 
00327 void Image_buffer16::copy_line8
00328   (
00329   unsigned char *src_pixels,  // Source rectangle pixels.
00330   int srcw,     // Width to copy.
00331   int destx, int desty
00332   )
00333   {
00334   int srcx = 0, srcy = 0, srch = 1;
00335           // Constrain to window's space.
00336   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00337     return;
00338   unsigned short *to = get_pixels() + desty*line_width + destx;
00339   unsigned char *from = src_pixels + srcx;
00340   for (int cnt = srcw; cnt; cnt--)
00341     *to++ = palette[*from++];
00342   }
00343 
00344 /*
00345  *  Copy another rectangle into this one, with 0 being the transparent
00346  *  color.
00347  */
00348 
00349 void Image_buffer16::copy_transparent8
00350   (
00351   unsigned char *src_pixels,  // Source rectangle pixels.
00352   int srcw, int srch,   // Dimensions of source.
00353   int destx, int desty
00354   )
00355   {
00356   int srcx = 0, srcy = 0;
00357   int src_width = srcw;   // Save full source width.
00358           // Constrain to window's space.
00359   if (!clip(srcx, srcy, srcw, srch, destx, desty))
00360     return;
00361   unsigned short *to = get_pixels() + desty*line_width + destx;
00362   unsigned char *from = src_pixels + srcy*src_width + srcx;
00363   int to_next = line_width - srcw;// # pixels to next line.
00364   int from_next = src_width - srcw;
00365   while (srch--)      // Do each line.
00366     {
00367     for (int cnt = srcw; cnt; cnt--, to++)
00368       {
00369       register int chr = *from++;
00370       if (chr)
00371         *to = palette[chr];
00372       }
00373     to += to_next;
00374     from += from_next;
00375     }
00376   }
00377 

Generated on Mon Jul 9 14:42:47 2007 for ExultEngine by  doxygen 1.5.1