Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

blit_mga.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: blit_mga.cpp,v 1.2 2001/03/10 17:26:28 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 
00014         TODO:
00015                 - m_alphablitter
00016                 - colorkeying with other than 16 bits per pixel
00017                 - 8 byte alignment for every sprite in the surface
00018                 - (config option for limiting offscreen images)
00019 */
00020 
00021 #include "Core/precomp.h"
00022 
00023 #include <Display/Display/FBDev/blit_mga.h>
00024 #include <Display/Display/Generic/blitters.h>
00025 #include <API/Display/Display/cliprect.h>
00026 #include <Display/Display/Generic/colormap.h>
00027 #include <Display/Display/FBDev/display_fbdev.h>
00028 #include <Display/Display/Generic/pixeldata.h>
00029 #include <API/Display/Display/surfaceprovider.h>
00030 #include <API/Display/Display/target.h>
00031 #include <Display/Display/Generic/blit_alphamask_rle.h>
00032 
00033 #include <linux/fb.h>
00034 
00035 #include "regs.h"
00036 #include "mmio.h"
00037 
00038 static int store_index = 0;
00039 
00040 std::list<CL_Blit_MGA*> CL_Blit_MGA::m_loaded_surfaces;
00041 
00042 CL_Blit_MGA::CL_Blit_MGA(
00043         CL_FBDev_DisplayCard *card,
00044         CL_SurfaceProvider *provider,
00045         volatile unsigned char *mmioaddr)
00046 {
00047         m_card = card;
00048         m_provider = provider;
00049         m_alphablitter = NULL;
00050         m_transparent = false;
00051         m_mmioaddr = mmioaddr;
00052 }
00053 
00054 CL_Blit_MGA::~CL_Blit_MGA()
00055 {
00056         if (m_alphablitter != NULL) delete m_alphablitter;
00057 }
00058 
00059 bool CL_Blit_MGA::init_surface(CL_Blitters *blitters)
00060 {
00061         m_width = m_provider->get_width();
00062         m_height = m_provider->get_height();
00063         
00064         /* sort big images out for cards with only 4Mb */
00065         if (m_card->get_total_memory() <= 4096*1024)
00066         {
00067                 if ((m_width>400) || (m_height>300)) return false;
00068         }
00069         
00070         if (!reload(false, true)) return false;
00071 
00072         blitters->set_clip(this);
00073         blitters->set_noclip(this);
00074 
00075         if (m_card->accel_scale_blit())
00076         {
00077                 blitters->set_scale_noclip(this);
00078                 blitters->set_scale_clip(this);
00079         }
00080 
00081         m_loaded_surfaces.push_back(this);
00082 
00083         return true;
00084 }
00085 
00086 void CL_Blit_MGA::blt_noclip(
00087         CL_Target *target,
00088         int x,
00089         int y,
00090         int spr_no)
00091 {
00092         int new_store = m_store;
00093         if (spr_no)
00094         {
00095                 new_store += spr_no*m_size;
00096         }
00097 
00098         y += m_card->yoffset;
00099 
00100         if (m_transparent)
00101         {
00102                 mga_waitfifo(m_mmioaddr, 7);
00103 
00104                 mga_out32(m_mmioaddr, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO | OP_BITBLT
00105                                         | SGNZERO | LINEAR | NOCLIP | ATYPE_RSTR | TRANS, DWGCTL);
00106                 mga_out32(m_mmioaddr, m_transcol, FCOL);
00107                 mga_out32(m_mmioaddr, 0xFFFFFFFF, BCOL);
00108         } else
00109         {
00110                 mga_waitfifo(m_mmioaddr, 5);
00111 
00112                 mga_out32(m_mmioaddr, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO | OP_BITBLT
00113                                         | SGNZERO | LINEAR | NOCLIP | ATYPE_RPL, DWGCTL);
00114         }
00115 
00116         mga_out32(m_mmioaddr, new_store, AR3);
00117         mga_out32(m_mmioaddr, new_store+m_size, AR0);
00118         mga_out32(m_mmioaddr, ((x + m_width-1) << 16) | x, FXBNDRY);
00119         mga_out32(m_mmioaddr, (y << 16) | m_height, YDSTLEN | EXECUTE);
00120 
00121 //      if (m_alphablitter != NULL) m_alphablitter->blt_noclip(target, x, y, spr_no);*/
00122 }
00123 
00124 void CL_Blit_MGA::blt_clip(
00125         CL_Target *target,
00126         int x,
00127         int y,
00128         int spr_no,
00129         const CL_ClipRect &clip)
00130 {
00131         int new_store = m_store;
00132         if (spr_no)
00133         {
00134                 new_store += spr_no*m_size;
00135         }
00136 
00137         y += m_card->yoffset;
00138 
00139         if (m_transparent)
00140         {
00141                 mga_waitfifo(m_mmioaddr, 7);
00142 
00143                 mga_out32(m_mmioaddr, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO | OP_BITBLT
00144                                         | SGNZERO | LINEAR | ATYPE_RSTR | TRANS, DWGCTL);
00145                 mga_out32(m_mmioaddr, m_transcol, FCOL);
00146                 mga_out32(m_mmioaddr, 0xFFFFFFFF, BCOL);
00147         } else
00148         {
00149                 mga_waitfifo(m_mmioaddr, 5);
00150 
00151                 mga_out32(m_mmioaddr, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO | OP_BITBLT
00152                                         | SGNZERO | LINEAR | ATYPE_RPL, DWGCTL);
00153         }
00154 
00155         mga_out32(m_mmioaddr, new_store, AR3);
00156         mga_out32(m_mmioaddr, new_store+m_size, AR0);
00157         mga_out32(m_mmioaddr, ((x + m_width-1) << 16) | x, FXBNDRY);
00158         mga_out32(m_mmioaddr, (y << 16) | m_height, YDSTLEN | EXECUTE);
00159         
00160 //      if (m_alphablitter != NULL) m_alphablitter->blt_noclip(target, x, y, spr_no);*/
00161 }
00162 
00163 void CL_Blit_MGA::blt_scale_noclip(
00164                 CL_Target *target,
00165                 int x,
00166                 int y,
00167                 int dest_width,
00168                 int dest_height,
00169                 int spr_no)
00170 {
00171         int new_store = m_store;
00172         if (spr_no)
00173         {
00174                 new_store += spr_no*m_size;
00175         }
00176 
00177         y += m_card->yoffset;
00178 
00179 
00180         if (m_transparent)
00181         {
00182                 mga_waitfifo( m_mmioaddr, 9 );
00183                 mga_out32( m_mmioaddr, DECALDIS, TEXCTL2 );
00184                 mga_out32( m_mmioaddr, 0xFFFF0000 | (m_transcol & 0xFFFF) | (1<<30), TEXTRANS );
00185         } else
00186         {
00187                 mga_waitfifo( m_mmioaddr, 8 );
00188                 mga_out32( m_mmioaddr, DECALDIS | CKSTRANSDIS, TEXCTL2 );
00189         }
00190 
00191         mga_out32( m_mmioaddr, BOP_COPY | SHFTZERO | SGNZERO | ARZERO | OP_TEXTURE_TRAP | ATYPE_I, DWGCTL );
00192         mga_out32( m_mmioaddr, (3<<27) | ((m_width)<<9) | LINEXT | TW16, TEXCTL );
00193         mga_out32( m_mmioaddr, (1<<20) | MAG_BILINEAR | MIN_BILINEAR, TEXFILTER );
00194         mga_out32( m_mmioaddr, ((m_width-1)<<18) | 2<<9 | 6, TEXWIDTH );
00195         mga_out32( m_mmioaddr, ((m_height-1)<<18) | 2<<9 | 6, TEXHEIGHT );
00196         mga_out32( m_mmioaddr, F1220(1/(float)(dest_width)), TMR0 );
00197         mga_out32( m_mmioaddr, 0, TMR1 );
00198 
00199         mga_waitfifo( m_mmioaddr, 10 );
00200         mga_out32( m_mmioaddr, 0, TMR2 );
00201         mga_out32( m_mmioaddr, F1220((1/(float)(dest_height)) / (m_width/(float)(m_height))), TMR3 );
00202         mga_out32( m_mmioaddr, 0, TMR4 );
00203         mga_out32( m_mmioaddr, 0, TMR5 );
00204         mga_out32( m_mmioaddr, 0, TMR6 );
00205         mga_out32( m_mmioaddr, 0, TMR7 );
00206         mga_out32( m_mmioaddr, F1616(64/(float)(m_width)), TMR8 );
00207         mga_out32( m_mmioaddr, new_store*2, TEXORG );
00208         mga_out32( m_mmioaddr, ((x+dest_width-1) << 16) | x, FXBNDRY );
00209         mga_out32( m_mmioaddr, (y << 16) | dest_height, YDSTLEN | EXECUTE );
00210 }
00211 
00212 void CL_Blit_MGA::blt_scale_clip(
00213                 CL_Target *target,
00214                 int x,
00215                 int y,
00216                 int dest_width,
00217                 int dest_height,
00218                 int spr_no,
00219                 const CL_ClipRect &clip)
00220 {
00221         int new_store = m_store;
00222         if (spr_no)
00223         {
00224                 new_store += spr_no*m_size;
00225         }
00226 
00227         y += m_card->yoffset;
00228 
00229 
00230         if (m_transparent)
00231         {
00232                 mga_waitfifo( m_mmioaddr, 9 );
00233                 mga_out32( m_mmioaddr, DECALDIS, TEXCTL2 );
00234                 mga_out32( m_mmioaddr, 0xFFFF0000 | (m_transcol & 0xFFFF) | (1<<30), TEXTRANS );
00235         } else
00236         {
00237                 mga_waitfifo( m_mmioaddr, 8 );
00238                 mga_out32( m_mmioaddr, DECALDIS | CKSTRANSDIS, TEXCTL2 );
00239         }
00240 
00241         mga_out32( m_mmioaddr, BOP_COPY | SHFTZERO | SGNZERO | ARZERO | OP_TEXTURE_TRAP | ATYPE_I, DWGCTL );
00242         mga_out32( m_mmioaddr, (3<<27) | ((m_width)<<9) | LINEXT | TW16, TEXCTL );
00243         mga_out32( m_mmioaddr, (1<<20) | MAG_BILINEAR | MIN_BILINEAR, TEXFILTER );
00244         mga_out32( m_mmioaddr, ((m_width-1)<<18) | 2<<9 | 6, TEXWIDTH );
00245         mga_out32( m_mmioaddr, ((m_height-1)<<18) | 2<<9 | 6, TEXHEIGHT );
00246         mga_out32( m_mmioaddr, F1220(1/(float)(dest_width)), TMR0 );
00247         mga_out32( m_mmioaddr, 0, TMR1 );
00248 
00249         mga_waitfifo( m_mmioaddr, 10 );
00250         mga_out32( m_mmioaddr, 0, TMR2 );
00251         mga_out32( m_mmioaddr, F1220((1/(float)(dest_height)) / (m_width/(float)(m_height))), TMR3 );
00252         mga_out32( m_mmioaddr, 0, TMR4 );
00253         mga_out32( m_mmioaddr, 0, TMR5 );
00254         mga_out32( m_mmioaddr, 0, TMR6 );
00255         mga_out32( m_mmioaddr, 0, TMR7 );
00256         mga_out32( m_mmioaddr, F1616(64/(float)(m_width)), TMR8 );
00257         mga_out32( m_mmioaddr, new_store*2, TEXORG );
00258         mga_out32( m_mmioaddr, ((x+dest_width-1) << 16) | x, FXBNDRY );
00259         mga_out32( m_mmioaddr, (y << 16) | dest_height, YDSTLEN | EXECUTE );
00260 }
00261 
00262 bool CL_Blit_MGA::reload(bool lock_provider, bool create_surface)
00263 {
00264         if (lock_provider) m_provider->lock();
00265 
00266         CL_PixelData input(
00267                 m_card->get_target()->get_red_mask(),
00268                 m_card->get_target()->get_green_mask(),
00269                 m_card->get_target()->get_blue_mask(),
00270                 m_card->get_target()->get_alpha_mask(),
00271                 m_provider,
00272                 (m_card->get_target()->get_depth()+7)/8);
00273 
00274         CL_PixelData alpha( 0, 0, 0, 255, m_provider, 1 );
00275         
00276         // always use 8 byte alignment
00277         while ((int)(m_card->get_offscreen_mem()+store_index*input.get_bytes_per_pixel()) %8)
00278         {
00279                 store_index++;
00280         }
00281 
00282         m_store = store_index + m_card->get_virt_width()*m_card->get_height()*2;
00283         m_size = m_width*m_height;
00284 
00285         if ((int)(m_card->get_target()->get_pitch()*m_card->get_height()*2+(store_index+m_size)*input.get_bytes_per_pixel()) > m_card->get_total_memory())
00286         {
00287                 // sorry, out of video ram
00288                 return false;
00289         }
00290         
00291         CL_ColorMap color_map(m_card->get_target());
00292         unsigned char* dest = m_card->get_offscreen_mem() + store_index * input.get_bytes_per_pixel();
00293         unsigned short trans_color = color_map.calc_color(0.05f, 0.05f, 0.05f, 0);
00294 
00295         m_transcol = (trans_color<<16) | trans_color; //FIXME: Support other bpp
00296 
00297         for( unsigned int i=0; i<m_height*m_provider->get_num_frames(); i++)
00298         {
00299                 memcpy( dest, input.get_line_pixel(i), input.get_bytes_pr_line() );
00300                 
00301                 unsigned short* dd = (unsigned short*)dest;
00302                 unsigned char* aa = alpha.get_line_pixel(i);
00303                 for ( int a=0; a<alpha.get_bytes_pr_line(); a++ )
00304                 {
00305                         if (*dd == trans_color)
00306                         {
00307                                 (*dd)++;
00308                         }
00309                         if (*aa != 255)
00310                         {
00311                                 *dd = trans_color;
00312                                 m_transparent = true;
00313                         }
00314                         aa++;
00315                         dd++;
00316                 }
00317 
00318                 dest += input.get_bytes_pr_line();
00319                 store_index += m_width;
00320         }
00321 
00322         if (lock_provider) m_provider->unlock();
00323 
00324 //      std::cout << "Offscreen memory in use: " << store_index * (m_card->get_target()->get_depth()+7)/8 << std::endl;
00325 
00326         return true;
00327 }
00328 
00329 void CL_Blit_MGA::reload_all_surfaces()
00330 {
00331         store_index = 0;
00332         for (
00333                 std::list<CL_Blit_MGA*>::iterator counter = m_loaded_surfaces.begin();
00334                 counter != m_loaded_surfaces.end();
00335                 counter++)
00336         {
00337                 (*counter)->reload(true, false);
00338         }
00339 }

Generated at Wed Apr 4 19:53:58 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001