2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Routines for bitblt ' s .
*
2009-11-30 22:42:55 +00:00
*/
2006-03-20 17:12:09 +00:00
2014-08-08 02:44:27 +00:00
# include <algorithm>
2014-07-01 00:23:30 +00:00
# include <utility>
2007-06-10 16:21:53 +00:00
# include <string.h>
2006-03-20 17:12:09 +00:00
# include "u_mem.h"
# include "gr.h"
# include "grdef.h"
# include "rle.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2014-07-03 01:47:29 +00:00
# include "byteutil.h"
2006-03-20 17:12:09 +00:00
# ifdef OGL
# include "ogl_init.h"
# endif
2014-07-01 02:30:39 +00:00
# include "compiler-array.h"
2014-12-05 03:29:33 +00:00
# include "compiler-exchange.h"
2014-07-01 02:30:39 +00:00
2015-12-13 18:00:49 +00:00
namespace dcx {
2015-12-05 22:57:23 +00:00
2013-06-08 23:35:21 +00:00
static int gr_bitblt_dest_step_shift = 0 ;
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
static void gr_bm_ubitblt00_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest ) ;
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-11-30 22:09:22 +00:00
static void gr_bm_ubitblt00m_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest ) ;
2014-11-30 22:09:22 +00:00
static void gr_bm_ubitblt0x_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest ) ;
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
# define gr_linear_movsd(S,D,L) memcpy(D,S,L)
2006-03-20 17:12:09 +00:00
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-12-05 02:42:43 +00:00
static void gr_linear_rep_movsdm ( const uint8_t * const src , uint8_t * const dest , const uint_fast32_t num_pixels )
{
auto predicate = [ & ] ( uint8_t s , uint8_t d ) {
return s = = 255 ? d : s ;
} ;
std : : transform ( src , src + num_pixels , dest , dest , predicate ) ;
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
static void gr_ubitmap00 ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2016-05-28 17:31:26 +00:00
const size_t src_width = bm . bm_w ;
const uintptr_t src_rowsize = bm . bm_rowsize ;
const uintptr_t dest_rowsize = grd_curcanv - > cv_bitmap . bm_rowsize < < gr_bitblt_dest_step_shift ;
2014-12-02 03:24:38 +00:00
auto dest = & ( grd_curcanv - > cv_bitmap . get_bitmap_data ( ) [ dest_rowsize * y + x ] ) ;
auto src = bm . get_bitmap_data ( ) ;
2006-03-20 17:12:09 +00:00
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t y1 = bm . bm_h ; y1 - - ; )
{
2016-05-28 17:31:26 +00:00
gr_linear_movsd ( src , dest , src_width ) ;
src + = src_rowsize ;
2015-02-05 03:03:49 +00:00
dest + = dest_rowsize ;
2006-03-20 17:12:09 +00:00
}
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-11-30 22:09:22 +00:00
static void gr_ubitmap00m ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
int dest_rowsize ;
dest_rowsize = grd_curcanv - > cv_bitmap . bm_rowsize < < gr_bitblt_dest_step_shift ;
2014-12-02 03:24:38 +00:00
auto dest = & ( grd_curcanv - > cv_bitmap . get_bitmap_data ( ) [ dest_rowsize * y + x ] ) ;
auto src = bm . get_bitmap_data ( ) ;
2006-03-20 17:12:09 +00:00
2015-02-14 22:48:27 +00:00
const uint_fast32_t bm_h = bm . bm_h ;
2015-07-21 02:57:27 +00:00
{
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t y1 = bm_h ; y1 - - ; )
{
2014-11-30 22:09:22 +00:00
gr_linear_rep_movsdm ( src , dest , bm . bm_w ) ;
src + = bm . bm_rowsize ;
2015-02-05 03:03:49 +00:00
dest + = dest_rowsize ;
2006-03-20 17:12:09 +00:00
}
}
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-12-05 02:44:01 +00:00
template < typename F >
static inline void gr_for_each_bitmap_byte ( const uint_fast32_t bx , const uint_fast32_t by , const grs_bitmap & bm , F f )
2006-03-20 17:12:09 +00:00
{
2014-11-30 22:09:18 +00:00
auto src = bm . bm_data ;
2014-12-05 02:44:01 +00:00
const auto ey = by + bm . bm_h ;
const auto ex = bx + bm . bm_w ;
for ( auto iy = by ; iy ! = ey ; + + iy )
for ( auto ix = bx ; ix ! = ex ; + + ix )
f ( bm , src + + , ix , iy ) ;
}
static void gr_ubitmap012 ( unsigned x , unsigned y , const grs_bitmap & bm )
{
2015-11-26 02:56:54 +00:00
const auto a = [ ] ( const grs_bitmap & , const uint8_t * const src , const uint_fast32_t px , const uint_fast32_t py ) {
2016-02-12 04:02:28 +00:00
const auto color = * src ;
gr_upixel ( px , py , color ) ;
2014-12-05 02:44:01 +00:00
} ;
gr_for_each_bitmap_byte ( x , y , bm , a ) ;
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-11-30 22:09:18 +00:00
static void gr_ubitmap012m ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2015-11-26 02:56:54 +00:00
const auto a = [ ] ( const grs_bitmap & , const uint8_t * const src , const uint_fast32_t px , const uint_fast32_t py ) {
2014-12-05 02:44:01 +00:00
const uint8_t c = * src ;
if ( c ! = 255 )
{
2016-02-12 04:02:28 +00:00
gr_upixel ( px , py , c ) ;
2006-03-20 17:12:09 +00:00
}
2014-12-05 02:44:01 +00:00
} ;
gr_for_each_bitmap_byte ( x , y , bm , a ) ;
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
static void gr_ubitmapGENERIC ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2015-02-14 22:48:27 +00:00
const uint_fast32_t bm_h = bm . bm_h ;
const uint_fast32_t bm_w = bm . bm_w ;
for ( uint_fast32_t y1 = 0 ; y1 ! = bm_h ; + + y1 )
{
for ( uint_fast32_t x1 = 0 ; x1 ! = bm_w ; + + x1 )
{
2016-02-12 04:02:28 +00:00
const auto color = gr_gpixel ( bm , x1 , y1 ) ;
gr_upixel ( x + x1 , y + y1 , color ) ;
2006-03-20 17:12:09 +00:00
}
}
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-11-30 22:09:19 +00:00
static void gr_ubitmapGENERICm ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2015-02-14 22:48:27 +00:00
const uint_fast32_t bm_h = bm . bm_h ;
const uint_fast32_t bm_w = bm . bm_w ;
for ( uint_fast32_t y1 = 0 ; y1 ! = bm_h ; + + y1 )
{
for ( uint_fast32_t x1 = 0 ; x1 ! = bm_w ; + + x1 )
{
2016-02-12 04:02:28 +00:00
const auto c = gr_gpixel ( bm , x1 , y1 ) ;
2009-11-30 22:42:55 +00:00
if ( c ! = 255 ) {
2016-02-12 04:02:28 +00:00
gr_upixel ( x + x1 , y + y1 , c ) ;
2006-03-20 17:12:09 +00:00
}
}
}
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-11-30 22:09:19 +00:00
void gr_ubitmap ( grs_bitmap & bm )
2015-07-25 23:10:47 +00:00
{
int dest ;
2014-11-30 22:09:19 +00:00
const unsigned x = 0 ;
const unsigned y = 0 ;
2009-11-30 22:42:55 +00:00
2015-07-25 23:10:47 +00:00
const auto source = bm . get_type ( ) ;
2009-11-30 22:42:55 +00:00
dest = TYPE ;
2016-05-28 17:31:26 +00:00
if ( source = = bm_mode : : linear ) {
2009-11-30 22:42:55 +00:00
switch ( dest )
{
2016-05-28 17:31:26 +00:00
case bm_mode : : linear :
2014-11-30 22:09:19 +00:00
if ( bm . bm_flags & BM_FLAG_RLE )
gr_bm_ubitblt00_rle ( bm . bm_w , bm . bm_h , x , y , 0 , 0 , bm , grd_curcanv - > cv_bitmap ) ;
2009-11-30 22:42:55 +00:00
else
gr_ubitmap00 ( x , y , bm ) ;
return ;
# ifdef OGL
2016-05-28 17:31:26 +00:00
case bm_mode : : ogl :
2016-02-12 04:02:28 +00:00
ogl_ubitmapm_cs ( x , y , - 1 , - 1 , bm , ogl_colors : : white , F1_0 ) ;
2009-11-30 22:42:55 +00:00
return ;
# endif
default :
2014-11-30 22:09:19 +00:00
gr_ubitmap012 ( x , y , bm ) ;
2009-11-30 22:42:55 +00:00
return ;
}
} else {
2014-11-30 22:09:19 +00:00
gr_ubitmapGENERIC ( x , y , bm ) ;
2009-11-30 22:42:55 +00:00
}
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-12-02 03:35:01 +00:00
void gr_ubitmapm ( unsigned x , unsigned y , grs_bitmap & bm )
{
2015-07-25 23:10:47 +00:00
const auto source = bm . get_type ( ) ;
2014-12-02 03:35:01 +00:00
auto dest = TYPE ;
2016-05-28 17:31:26 +00:00
if ( source = = bm_mode : : linear ) {
2009-11-30 22:42:55 +00:00
switch ( dest )
{
2016-05-28 17:31:26 +00:00
case bm_mode : : linear :
2014-12-02 03:35:01 +00:00
if ( bm . bm_flags & BM_FLAG_RLE )
gr_bm_ubitblt00m_rle ( bm . bm_w , bm . bm_h , x , y , 0 , 0 , bm , grd_curcanv - > cv_bitmap ) ;
2009-11-30 22:42:55 +00:00
else
2014-12-02 03:35:01 +00:00
gr_ubitmap00m ( x , y , bm ) ;
2009-11-30 22:42:55 +00:00
return ;
# ifdef OGL
2016-05-28 17:31:26 +00:00
case bm_mode : : ogl :
2016-02-12 04:02:28 +00:00
ogl_ubitmapm_cs ( x , y , - 1 , - 1 , bm , ogl_colors : : white , F1_0 ) ;
2009-11-30 22:42:55 +00:00
return ;
# endif
default :
2014-12-02 03:35:01 +00:00
gr_ubitmap012m ( x , y , bm ) ;
2009-11-30 22:42:55 +00:00
return ;
}
} else {
2014-12-02 03:35:01 +00:00
gr_ubitmapGENERICm ( x , y , bm ) ;
2009-11-30 22:42:55 +00:00
}
}
2006-03-20 17:12:09 +00:00
// From Linear to Linear
2014-12-02 03:35:01 +00:00
static void gr_bm_ubitblt00 ( unsigned w , unsigned h , unsigned dx , unsigned dy , unsigned sx , unsigned sy , const grs_bitmap & src , grs_bitmap & dest )
2006-03-20 17:12:09 +00:00
{
2009-11-30 22:42:55 +00:00
//int src_bm_rowsize_2, dest_bm_rowsize_2;
2014-12-02 03:35:01 +00:00
auto sbits = & src . get_bitmap_data ( ) [ ( src . bm_rowsize * sy ) + sx ] ;
auto dbits = & dest . get_bitmap_data ( ) [ ( dest . bm_rowsize * dy ) + dx ] ;
auto dstep = dest . bm_rowsize < < gr_bitblt_dest_step_shift ;
2006-03-20 17:12:09 +00:00
// No interlacing, copy the whole buffer.
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t i = h ; i - - ; )
{
2009-11-30 22:42:55 +00:00
gr_linear_movsd ( sbits , dbits , w ) ;
//memcpy(dbits, sbits, w);
2014-12-02 03:35:01 +00:00
sbits + = src . bm_rowsize ;
2009-11-30 22:42:55 +00:00
dbits + = dstep ;
}
2006-03-20 17:12:09 +00:00
}
2009-11-30 22:42:55 +00:00
2006-03-20 17:12:09 +00:00
// From Linear to Linear Masked
2014-12-05 03:31:07 +00:00
static void gr_bm_ubitblt00m ( const unsigned w , const uint_fast32_t h , unsigned dx , unsigned dy , unsigned sx , unsigned sy , const grs_bitmap & src , grs_bitmap & dest )
2006-03-20 17:12:09 +00:00
{
2009-11-30 22:42:55 +00:00
//int src_bm_rowsize_2, dest_bm_rowsize_2;
2014-12-02 03:35:01 +00:00
auto sbits = & src . get_bitmap_data ( ) [ ( src . bm_rowsize * sy ) + sx ] ;
auto dbits = & dest . get_bitmap_data ( ) [ ( dest . bm_rowsize * dy ) + dx ] ;
2006-03-20 17:12:09 +00:00
// No interlacing, copy the whole buffer.
2015-07-21 02:57:27 +00:00
{
2014-12-05 03:31:07 +00:00
for ( auto i = h ; i ; - - i )
{
2006-03-20 17:12:09 +00:00
gr_linear_rep_movsdm ( sbits , dbits , w ) ;
2014-12-02 03:35:01 +00:00
sbits + = src . bm_rowsize ;
dbits + = dest . bm_rowsize ;
2006-03-20 17:12:09 +00:00
}
}
}
2014-12-02 03:35:01 +00:00
void gr_bm_ubitblt ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest )
2006-03-20 17:12:09 +00:00
{
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : linear & & dest . get_type ( ) = = bm_mode : : linear )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
if ( src . bm_flags & BM_FLAG_RLE )
gr_bm_ubitblt00_rle ( w , h , dx , dy , sx , sy , src , dest ) ;
2006-03-20 17:12:09 +00:00
else
2014-12-02 03:35:01 +00:00
gr_bm_ubitblt00 ( w , h , dx , dy , sx , sy , src , dest ) ;
2006-03-20 17:12:09 +00:00
return ;
}
# ifdef OGL
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : linear & & dest . get_type ( ) = = bm_mode : : ogl )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
ogl_ubitblt ( w , h , dx , dy , sx , sy , src , dest ) ;
2006-03-20 17:12:09 +00:00
return ;
}
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : ogl & & dest . get_type ( ) = = bm_mode : : linear )
2006-03-20 17:12:09 +00:00
{
return ;
}
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : ogl & & dest . get_type ( ) = = bm_mode : : ogl )
2006-03-20 17:12:09 +00:00
{
return ;
}
# endif
2016-05-28 17:31:26 +00:00
if ( ( src . bm_flags & BM_FLAG_RLE ) & & src . get_type ( ) = = bm_mode : : linear )
2015-07-25 23:10:47 +00:00
{
2014-12-02 03:35:01 +00:00
gr_bm_ubitblt0x_rle ( w , h , dx , dy , sx , sy , src , dest ) ;
2009-11-30 22:42:55 +00:00
return ;
2006-03-20 17:12:09 +00:00
}
2014-12-05 03:31:07 +00:00
for ( uint_fast32_t y1 = 0 ; y1 ! = h ; + + y1 )
for ( uint_fast32_t x1 = 0 ; x1 ! = w ; + + x1 )
2014-12-02 03:35:01 +00:00
gr_bm_pixel ( dest , dx + x1 , dy + y1 , gr_gpixel ( src , sx + x1 , sy + y1 ) ) ;
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
2010-06-18 07:31:06 +00:00
// Clipped bitmap ...
2014-12-02 03:35:01 +00:00
void gr_bitmap ( unsigned x , unsigned y , grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
int dx1 = x , dx2 = x + bm . bm_w - 1 ;
int dy1 = y , dy2 = y + bm . bm_h - 1 ;
2012-04-15 14:15:21 +00:00
# ifndef OGL
2009-11-30 22:42:55 +00:00
int sx = 0 , sy = 0 ;
2012-04-15 14:15:21 +00:00
# endif
2006-03-20 17:12:09 +00:00
2009-11-30 22:42:55 +00:00
if ( ( dx1 > = grd_curcanv - > cv_bitmap . bm_w ) | | ( dx2 < 0 ) ) return ;
if ( ( dy1 > = grd_curcanv - > cv_bitmap . bm_h ) | | ( dy2 < 0 ) ) return ;
2013-06-23 04:34:40 +00:00
// Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
# ifdef OGL
2016-02-12 04:02:28 +00:00
ogl_ubitmapm_cs ( x , y , 0 , 0 , bm , ogl_colors : : white , F1_0 ) ;
2013-06-23 04:34:40 +00:00
# else
2012-04-15 14:15:21 +00:00
if ( dx1 < 0 )
{
sx = - dx1 ;
dx1 = 0 ;
}
if ( dy1 < 0 )
{
sy = - dy1 ;
dy1 = 0 ;
}
2009-11-30 22:42:55 +00:00
if ( dx2 > = grd_curcanv - > cv_bitmap . bm_w ) { dx2 = grd_curcanv - > cv_bitmap . bm_w - 1 ; }
if ( dy2 > = grd_curcanv - > cv_bitmap . bm_h ) { dy2 = grd_curcanv - > cv_bitmap . bm_h - 1 ; }
2010-06-18 07:31:06 +00:00
2014-12-02 03:35:01 +00:00
gr_bm_ubitblt ( dx2 - dx1 + 1 , dy2 - dy1 + 1 , dx1 , dy1 , sx , sy , bm , grd_curcanv - > cv_bitmap ) ;
2012-04-09 09:30:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-12-02 03:35:01 +00:00
void gr_bitmapm ( unsigned x , unsigned y , const grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
int dx1 = x , dx2 = x + bm . bm_w - 1 ;
int dy1 = y , dy2 = y + bm . bm_h - 1 ;
2006-03-20 17:12:09 +00:00
int sx = 0 , sy = 0 ;
if ( ( dx1 > = grd_curcanv - > cv_bitmap . bm_w ) | | ( dx2 < 0 ) ) return ;
if ( ( dy1 > = grd_curcanv - > cv_bitmap . bm_h ) | | ( dy2 < 0 ) ) return ;
if ( dx1 < 0 ) { sx = - dx1 ; dx1 = 0 ; }
if ( dy1 < 0 ) { sy = - dy1 ; dy1 = 0 ; }
2009-11-30 22:42:55 +00:00
if ( dx2 > = grd_curcanv - > cv_bitmap . bm_w ) { dx2 = grd_curcanv - > cv_bitmap . bm_w - 1 ; }
if ( dy2 > = grd_curcanv - > cv_bitmap . bm_h ) { dy2 = grd_curcanv - > cv_bitmap . bm_h - 1 ; }
2010-06-18 07:31:06 +00:00
2006-03-20 17:12:09 +00:00
// Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
2016-05-28 17:31:26 +00:00
if ( bm . get_type ( ) = = bm_mode : : linear & & grd_curcanv - > cv_bitmap . get_type ( ) = = bm_mode : : linear )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
if ( bm . bm_flags & BM_FLAG_RLE )
gr_bm_ubitblt00m_rle ( dx2 - dx1 + 1 , dy2 - dy1 + 1 , dx1 , dy1 , sx , sy , bm , grd_curcanv - > cv_bitmap ) ;
2006-03-20 17:12:09 +00:00
else
2014-12-02 03:35:01 +00:00
gr_bm_ubitblt00m ( dx2 - dx1 + 1 , dy2 - dy1 + 1 , dx1 , dy1 , sx , sy , bm , grd_curcanv - > cv_bitmap ) ;
2006-03-20 17:12:09 +00:00
return ;
}
2014-12-02 03:35:01 +00:00
gr_bm_ubitbltm ( dx2 - dx1 + 1 , dy2 - dy1 + 1 , dx1 , dy1 , sx , sy , bm , grd_curcanv - > cv_bitmap ) ;
2006-03-20 17:12:09 +00:00
}
2014-12-02 03:35:01 +00:00
void gr_bm_ubitbltm ( unsigned w , unsigned h , unsigned dx , unsigned dy , unsigned sx , unsigned sy , const grs_bitmap & src , grs_bitmap & dest )
2006-03-20 17:12:09 +00:00
{
ubyte c ;
# ifdef OGL
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : linear & & dest . get_type ( ) = = bm_mode : : ogl )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
ogl_ubitblt ( w , h , dx , dy , sx , sy , src , dest ) ;
2006-03-20 17:12:09 +00:00
return ;
}
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : ogl & & dest . get_type ( ) = = bm_mode : : linear )
2006-03-20 17:12:09 +00:00
{
return ;
}
2016-05-28 17:31:26 +00:00
if ( src . get_type ( ) = = bm_mode : : ogl & & dest . get_type ( ) = = bm_mode : : ogl )
2006-03-20 17:12:09 +00:00
{
return ;
}
# endif
2014-12-05 03:31:07 +00:00
for ( uint_fast32_t y1 = 0 ; y1 ! = h ; + + y1 )
for ( uint_fast32_t x1 = 0 ; x1 ! = w ; + + x1 )
2014-12-02 03:35:01 +00:00
if ( ( c = gr_gpixel ( src , sx + x1 , sy + y1 ) ) ! = 255 )
gr_bm_pixel ( dest , dx + x1 , dy + y1 , c ) ;
2009-11-30 22:42:55 +00:00
}
2015-12-04 03:36:31 +00:00
# endif
2009-11-30 22:42:55 +00:00
2014-11-30 22:09:19 +00:00
static void gr_bm_ubitblt00_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest )
2009-11-30 22:42:55 +00:00
{
2014-09-26 02:42:13 +00:00
int data_offset ;
2010-06-18 07:31:06 +00:00
2009-11-30 22:42:55 +00:00
data_offset = 1 ;
2014-11-30 22:09:19 +00:00
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2009-11-30 22:42:55 +00:00
data_offset = 2 ;
2014-12-02 03:24:38 +00:00
auto sbits = & src . get_bitmap_data ( ) [ 4 + ( src . bm_h * data_offset ) ] ;
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t i = 0 ; i ! = sy ; + + i )
2015-04-02 02:36:52 +00:00
sbits + = src . bm_data [ 4 + ( i * data_offset ) ] ;
2014-12-02 03:24:38 +00:00
auto dbits = & dest . get_bitmap_data ( ) [ ( dest . bm_rowsize * dy ) + dx ] ;
2009-11-30 22:42:55 +00:00
// No interlacing, copy the whole buffer.
2014-12-05 03:31:07 +00:00
for ( uint_fast32_t i = 0 ; i ! = h ; + + i )
{
2009-11-30 22:42:55 +00:00
gr_rle_expand_scanline ( dbits , sbits , sx , sx + w - 1 ) ;
2014-11-30 22:09:19 +00:00
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2015-06-13 22:42:21 +00:00
sbits + = GET_INTEL_SHORT ( & src . bm_data [ 4 + ( ( i + sy ) * data_offset ) ] ) ;
2009-11-30 22:42:55 +00:00
else
2014-11-30 22:09:19 +00:00
sbits + = ( int ) ( src . bm_data [ 4 + i + sy ] ) ;
dbits + = dest . bm_rowsize < < gr_bitblt_dest_step_shift ;
2009-11-30 22:42:55 +00:00
}
2006-03-20 17:12:09 +00:00
}
2015-12-04 03:36:31 +00:00
# ifndef OGL
2014-11-30 22:09:22 +00:00
static void gr_bm_ubitblt00m_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest )
2009-11-30 22:42:55 +00:00
{
2014-09-26 02:42:13 +00:00
int data_offset ;
2010-06-18 07:31:06 +00:00
2009-11-30 22:42:55 +00:00
data_offset = 1 ;
2014-11-30 22:09:22 +00:00
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2009-11-30 22:42:55 +00:00
data_offset = 2 ;
2014-12-02 03:24:38 +00:00
auto sbits = & src . get_bitmap_data ( ) [ 4 + ( src . bm_h * data_offset ) ] ;
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t i = 0 ; i ! = sy ; + + i )
2015-04-02 02:36:52 +00:00
sbits + = src . bm_data [ 4 + ( i * data_offset ) ] ;
2014-12-02 03:24:38 +00:00
auto dbits = & dest . get_bitmap_data ( ) [ ( dest . bm_rowsize * dy ) + dx ] ;
2009-11-30 22:42:55 +00:00
// No interlacing, copy the whole buffer.
2014-12-05 03:31:07 +00:00
for ( uint_fast32_t i = 0 ; i ! = h ; + + i )
{
2009-11-30 22:42:55 +00:00
gr_rle_expand_scanline_masked ( dbits , sbits , sx , sx + w - 1 ) ;
2014-11-30 22:09:22 +00:00
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2015-06-13 22:42:21 +00:00
sbits + = GET_INTEL_SHORT ( & src . bm_data [ 4 + ( ( i + sy ) * data_offset ) ] ) ;
2009-11-30 22:42:55 +00:00
else
2014-11-30 22:09:22 +00:00
sbits + = ( int ) ( src . bm_data [ 4 + i + sy ] ) ;
dbits + = dest . bm_rowsize < < gr_bitblt_dest_step_shift ;
2009-11-30 22:42:55 +00:00
}
}
// in rle.c
2014-11-30 22:09:22 +00:00
static void gr_bm_ubitblt0x_rle ( unsigned w , unsigned h , int dx , int dy , int sx , int sy , const grs_bitmap & src , grs_bitmap & dest )
2009-11-30 22:42:55 +00:00
{
2014-09-26 02:42:13 +00:00
int data_offset ;
2009-11-30 22:42:55 +00:00
data_offset = 1 ;
2014-11-30 22:09:22 +00:00
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2009-11-30 22:42:55 +00:00
data_offset = 2 ;
2014-12-02 03:24:38 +00:00
auto sbits = & src . bm_data [ 4 + ( src . bm_h * data_offset ) ] ;
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t i = 0 ; i ! = sy ; + + i )
2015-04-02 02:36:52 +00:00
sbits + = src . bm_data [ 4 + ( i * data_offset ) ] ;
2010-06-18 07:31:06 +00:00
2014-12-05 03:31:07 +00:00
for ( uint_fast32_t y1 = 0 ; y1 ! = h ; + + y1 )
{
2014-11-30 22:09:22 +00:00
gr_rle_expand_scanline_generic ( dest , dx , dy + y1 , sbits , sx , sx + w - 1 ) ;
if ( src . bm_flags & BM_FLAG_RLE_BIG )
2015-06-13 22:42:21 +00:00
sbits + = GET_INTEL_SHORT ( & src . bm_data [ 4 + ( ( y1 + sy ) * data_offset ) ] ) ;
2009-11-30 22:42:55 +00:00
else
2014-11-30 22:09:22 +00:00
sbits + = ( int ) src . bm_data [ 4 + y1 + sy ] ;
2009-11-30 22:42:55 +00:00
}
}
2015-12-04 03:36:31 +00:00
# endif
2006-03-20 17:12:09 +00:00
// rescalling bitmaps, 10/14/99 Jan Bobrowski jb@wizard.ae.krakow.pl
2014-12-05 03:29:33 +00:00
static void scale_line ( const uint8_t * in , uint8_t * out , const uint_fast32_t ilen , const uint_fast32_t olen )
2006-03-20 17:12:09 +00:00
{
2014-12-05 03:29:33 +00:00
uint_fast32_t a = olen / ilen , b = olen % ilen , c = 0 ;
for ( uint8_t * const end = out + olen ; out ! = end ; )
{
uint_fast32_t i = a ;
2006-03-20 17:12:09 +00:00
c + = b ;
if ( c > = ilen ) {
c - = ilen ;
2014-12-05 03:29:33 +00:00
+ + i ;
2006-03-20 17:12:09 +00:00
}
2014-12-08 00:41:03 +00:00
auto e = out + i ;
2014-12-05 03:29:33 +00:00
std : : fill ( exchange ( out , e ) , e , * in + + ) ;
2006-03-20 17:12:09 +00:00
}
}
2014-12-02 03:35:01 +00:00
static void gr_bitmap_scale_to ( const grs_bitmap & src , grs_bitmap & dst )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
auto s = src . get_bitmap_data ( ) ;
auto d = dst . get_bitmap_data ( ) ;
int h = src . bm_h ;
int a = dst . bm_h / h , b = dst . bm_h % h ;
2014-09-26 02:42:13 +00:00
int c = 0 , i ;
2006-03-20 17:12:09 +00:00
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t y = src . bm_h ; y ; - - y ) {
2006-03-20 17:12:09 +00:00
i = a ;
c + = b ;
if ( c > = h ) {
c - = h ;
goto inside ;
}
while ( - - i > = 0 ) {
2009-11-30 22:42:55 +00:00
inside :
2014-12-02 03:35:01 +00:00
scale_line ( s , d , src . bm_w , dst . bm_w ) ;
d + = dst . bm_rowsize ;
2006-03-20 17:12:09 +00:00
}
2014-12-02 03:35:01 +00:00
s + = src . bm_rowsize ;
2006-03-20 17:12:09 +00:00
}
}
2014-12-02 03:35:01 +00:00
void show_fullscr ( grs_bitmap & bm )
2006-03-20 17:12:09 +00:00
{
2014-12-02 03:35:01 +00:00
auto & scr = grd_curcanv - > cv_bitmap ;
2006-03-20 17:12:09 +00:00
# ifdef OGL
2016-05-28 17:31:26 +00:00
if ( bm . get_type ( ) = = bm_mode : : linear & & scr . get_type ( ) = = bm_mode : : ogl & &
2015-03-22 18:49:21 +00:00
bm . bm_w < = grd_curscreen - > get_screen_width ( ) & & bm . bm_h < = grd_curscreen - > get_screen_height ( ) ) // only scale with OGL if bitmap is not bigger than screen size
2007-02-06 19:23:33 +00:00
{
2016-02-12 04:02:28 +00:00
ogl_ubitmapm_cs ( 0 , 0 , - 1 , - 1 , bm , ogl_colors : : white , F1_0 ) ; //use opengl to scale, faster and saves ram. -MPM
2006-03-20 17:12:09 +00:00
return ;
}
# endif
2016-05-28 17:31:26 +00:00
if ( scr . get_type ( ) ! = bm_mode : : linear )
2015-07-25 23:10:47 +00:00
{
2014-12-02 03:35:01 +00:00
grs_bitmap_ptr p = gr_create_bitmap ( scr . bm_w , scr . bm_h ) ;
auto & tmp = * p . get ( ) ;
gr_bitmap_scale_to ( bm , tmp ) ;
gr_bitmap ( 0 , 0 , tmp ) ;
2006-03-20 17:12:09 +00:00
return ;
}
2014-12-02 03:35:01 +00:00
gr_bitmap_scale_to ( bm , scr ) ;
2006-03-20 17:12:09 +00:00
}
2010-06-18 07:31:06 +00:00
// Find transparent area in bitmap
2014-12-02 03:35:01 +00:00
void gr_bitblt_find_transparent_area ( const grs_bitmap & bm , unsigned & minx , unsigned & miny , unsigned & maxx , unsigned & maxy )
2010-06-18 07:31:06 +00:00
{
2014-07-01 02:30:39 +00:00
using std : : advance ;
2014-07-01 00:23:30 +00:00
using std : : min ;
using std : : max ;
2010-06-18 07:31:06 +00:00
2014-12-02 03:35:01 +00:00
if ( ! ( bm . bm_flags & BM_FLAG_TRANSPARENT ) )
2010-06-18 07:31:06 +00:00
return ;
2014-12-02 03:35:01 +00:00
minx = bm . bm_w - 1 ;
2014-07-01 00:23:30 +00:00
maxx = 0 ;
2014-12-02 03:35:01 +00:00
miny = bm . bm_h - 1 ;
2014-07-01 00:23:30 +00:00
maxy = 0 ;
2010-06-18 07:31:06 +00:00
2014-07-01 02:30:39 +00:00
unsigned i = 0 , count = 0 ;
auto check = [ & ] ( unsigned x , unsigned y , ubyte c ) {
if ( c = = TRANSPARENCY_COLOR ) { // don't look for transparancy color here.
count + + ;
minx = min ( x , minx ) ;
miny = min ( y , miny ) ;
maxx = max ( x , maxx ) ;
maxy = max ( y , maxy ) ;
}
} ;
2010-06-18 07:31:06 +00:00
// decode the bitmap
2015-02-14 22:48:27 +00:00
const uint_fast32_t bm_h = bm . bm_h ;
const uint_fast32_t bm_w = bm . bm_w ;
2014-12-02 03:35:01 +00:00
if ( bm . bm_flags & BM_FLAG_RLE ) {
2014-07-01 02:30:39 +00:00
unsigned data_offset ;
2010-06-18 07:31:06 +00:00
data_offset = 1 ;
2014-12-02 03:35:01 +00:00
if ( bm . bm_flags & BM_FLAG_RLE_BIG )
2010-06-18 07:31:06 +00:00
data_offset = 2 ;
2014-12-02 03:35:01 +00:00
auto sbits = & bm . get_bitmap_data ( ) [ 4 + ( bm . bm_h * data_offset ) ] ;
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t y = 0 ; y ! = bm_h ; + + y )
2014-07-01 02:30:39 +00:00
{
array < ubyte , 4096 > buf ;
2014-12-02 03:35:01 +00:00
gr_rle_decode ( { sbits , begin ( buf ) } , rle_end ( bm , buf ) ) ;
advance ( sbits , bm . bm_data [ 4 + i ] | ( data_offset = = 2 ? static_cast < unsigned > ( bm . bm_data [ 5 + i ] ) < < 8 : 0 ) ) ;
2014-07-01 02:30:39 +00:00
i + = data_offset ;
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t x = 0 ; x ! = bm_w ; + + x )
2014-07-01 02:30:39 +00:00
check ( x , y , buf [ x ] ) ;
2010-06-18 07:31:06 +00:00
}
}
else
{
2015-02-14 22:48:27 +00:00
for ( uint_fast32_t y = 0 ; y ! = bm_h ; + + y )
for ( uint_fast32_t x = 0 ; x ! = bm_w ; + + x )
2014-12-02 03:35:01 +00:00
check ( x , y , bm . bm_data [ i + + ] ) ;
2010-06-18 07:31:06 +00:00
}
Assert ( count ) ;
}
2015-12-05 22:57:23 +00:00
}