8bpp_base.cpp

Go to the documentation of this file.
00001 /* $Id: 8bpp_base.cpp 18907 2010-01-23 22:37:14Z alberth $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../stdafx.h"
00013 #include "../gfx_func.h"
00014 #include "8bpp_base.hpp"
00015 
00016 void Blitter_8bppBase::DrawColourMappingRect(void *dst, int width, int height, PaletteID pal)
00017 {
00018   const uint8 *ctab = GetNonSprite(pal, ST_RECOLOUR) + 1;
00019 
00020   do {
00021     for (int i = 0; i != width; i++) *((uint8 *)dst + i) = ctab[((uint8 *)dst)[i]];
00022     dst = (uint8 *)dst + _screen.pitch;
00023   } while (--height);
00024 }
00025 
00026 void *Blitter_8bppBase::MoveTo(const void *video, int x, int y)
00027 {
00028   return (uint8 *)video + x + y * _screen.pitch;
00029 }
00030 
00031 void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8 colour)
00032 {
00033   *((uint8 *)video + x + y * _screen.pitch) = colour;
00034 }
00035 
00036 void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour)
00037 {
00038   do {
00039     memset(video, colour, width);
00040     video = (uint8 *)video + _screen.pitch;
00041   } while (--height);
00042 }
00043 
00044 void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour)
00045 {
00046   int dy;
00047   int dx;
00048   int stepx;
00049   int stepy;
00050   int frac;
00051 
00052   dy = (y2 - y) * 2;
00053   if (dy < 0) {
00054     dy = -dy;
00055     stepy = -1;
00056   } else {
00057     stepy = 1;
00058   }
00059 
00060   dx = (x2 - x) * 2;
00061   if (dx < 0) {
00062     dx = -dx;
00063     stepx = -1;
00064   } else {
00065     stepx = 1;
00066   }
00067 
00068   if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, colour);
00069   if (dx > dy) {
00070     frac = dy - (dx / 2);
00071     while (x != x2) {
00072       if (frac >= 0) {
00073         y += stepy;
00074         frac -= dx;
00075       }
00076       x += stepx;
00077       frac += dy;
00078       if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, colour);
00079     }
00080   } else {
00081     frac = dx - (dy / 2);
00082     while (y != y2) {
00083       if (frac >= 0) {
00084         x += stepx;
00085         frac -= dy;
00086       }
00087       y += stepy;
00088       frac += dx;
00089       if (x >= 0 && y >= 0 && x < screen_width && y < screen_height) this->SetPixel(video, x, y, colour);
00090     }
00091   }
00092 }
00093 
00094 void Blitter_8bppBase::CopyFromBuffer(void *video, const void *src, int width, int height)
00095 {
00096   uint8 *dst = (uint8 *)video;
00097   uint8 *usrc = (uint8 *)src;
00098 
00099   for (; height > 0; height--) {
00100     memcpy(dst, usrc, width * sizeof(uint8));
00101     usrc += width;
00102     dst += _screen.pitch;
00103   }
00104 }
00105 
00106 void Blitter_8bppBase::CopyToBuffer(const void *video, void *dst, int width, int height)
00107 {
00108   uint8 *udst = (uint8 *)dst;
00109   uint8 *src = (uint8 *)video;
00110 
00111   for (; height > 0; height--) {
00112     memcpy(udst, src, width * sizeof(uint8));
00113     src += _screen.pitch;
00114     udst += width;
00115   }
00116 }
00117 
00118 void Blitter_8bppBase::CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch)
00119 {
00120   uint8 *udst = (uint8 *)dst;
00121   uint8 *src = (uint8 *)video;
00122 
00123   for (; height > 0; height--) {
00124     memcpy(udst, src, width * sizeof(uint8));
00125     src += _screen.pitch;
00126     udst += dst_pitch;
00127   }
00128 }
00129 
00130 void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y)
00131 {
00132   const uint8 *src;
00133   uint8 *dst;
00134 
00135   if (scroll_y > 0) {
00136     /* Calculate pointers */
00137     dst = (uint8 *)video + left + (top + height - 1) * _screen.pitch;
00138     src = dst - scroll_y * _screen.pitch;
00139 
00140     /* Decrease height and increase top */
00141     top += scroll_y;
00142     height -= scroll_y;
00143     assert(height > 0);
00144 
00145     /* Adjust left & width */
00146     if (scroll_x >= 0) {
00147       dst += scroll_x;
00148       left += scroll_x;
00149       width -= scroll_x;
00150     } else {
00151       src -= scroll_x;
00152       width += scroll_x;
00153     }
00154 
00155     for (int h = height; h > 0; h--) {
00156       memcpy(dst, src, width * sizeof(uint8));
00157       src -= _screen.pitch;
00158       dst -= _screen.pitch;
00159     }
00160   } else {
00161     /* Calculate pointers */
00162     dst = (uint8 *)video + left + top * _screen.pitch;
00163     src = dst - scroll_y * _screen.pitch;
00164 
00165     /* Decrese height. (scroll_y is <=0). */
00166     height += scroll_y;
00167     assert(height > 0);
00168 
00169     /* Adjust left & width */
00170     if (scroll_x >= 0) {
00171       dst += scroll_x;
00172       left += scroll_x;
00173       width -= scroll_x;
00174     } else {
00175       src -= scroll_x;
00176       width += scroll_x;
00177     }
00178 
00179     /* the y-displacement may be 0 therefore we have to use memmove,
00180      * because source and destination may overlap */
00181     for (int h = height; h > 0; h--) {
00182       memmove(dst, src, width * sizeof(uint8));
00183       src += _screen.pitch;
00184       dst += _screen.pitch;
00185     }
00186   }
00187 }
00188 
00189 int Blitter_8bppBase::BufferSize(int width, int height)
00190 {
00191   return width * height;
00192 }
00193 
00194 void Blitter_8bppBase::PaletteAnimate(uint start, uint count)
00195 {
00196   /* Video backend takes care of the palette animation */
00197 }
00198 
00199 Blitter::PaletteAnimation Blitter_8bppBase::UsePaletteAnimation()
00200 {
00201   return Blitter::PALETTE_ANIMATION_VIDEO_BACKEND;
00202 }