dxx-rebirth/common/2d/bitblt.cpp

578 lines
15 KiB
C++
Raw Normal View History

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.
*
*/
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>
#include <string.h>
2006-03-20 17:12:09 +00:00
#include "u_mem.h"
#include "gr.h"
#include "grdef.h"
#include "rle.h"
#include "dxxerror.h"
#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"
#include "compiler-exchange.h"
2014-07-01 02:30:39 +00:00
2015-12-05 22:57:23 +00:00
inline namespace dcx {
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
#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
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
{
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
for (uint_fast32_t y1 = bm.bm_h; y1 --;)
{
2014-11-30 22:09:19 +00:00
gr_linear_movsd( src, dest, bm.bm_w );
src += bm.bm_rowsize;
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-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;
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) {
2014-12-05 02:44:01 +00:00
gr_setcolor(*src);
2015-11-26 02:56:54 +00:00
gr_upixel(px, py);
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)
{
gr_setcolor(c);
2015-11-26 02:56:54 +00:00
gr_upixel(px, py);
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)
{
2014-11-30 22:09:19 +00:00
gr_setcolor( gr_gpixel(bm,x1,y1) );
2006-03-20 17:12:09 +00:00
gr_upixel( x+x1, y+y1 );
}
}
}
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
{
ubyte c;
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)
{
2014-11-30 22:09:19 +00:00
c = gr_gpixel(bm,x1,y1);
if ( c != 255 ) {
2006-03-20 17:12:09 +00:00
gr_setcolor( c );
gr_upixel( x+x1, y+y1 );
}
}
}
}
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;
2015-07-25 23:10:47 +00:00
const auto source = bm.get_type();
dest = TYPE;
if (source==BM_LINEAR) {
switch( dest )
{
case BM_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 );
else
gr_ubitmap00( x, y, bm );
return;
#ifdef OGL
case BM_OGL:
2014-11-30 22:09:19 +00:00
ogl_ubitmapm_cs(x,y,-1,-1,bm,-1,F1_0);
return;
#endif
default:
2014-11-30 22:09:19 +00:00
gr_ubitmap012( x, y, bm );
return;
}
} else {
2014-11-30 22:09:19 +00:00
gr_ubitmapGENERIC(x, y, bm);
}
}
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;
if (source==BM_LINEAR) {
switch( dest )
{
case BM_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 );
else
2014-12-02 03:35:01 +00:00
gr_ubitmap00m(x, y, bm);
return;
#ifdef OGL
case BM_OGL:
2014-12-02 03:35:01 +00:00
ogl_ubitmapm_cs(x,y,-1,-1,bm,-1,F1_0);
return;
#endif
default:
2014-12-02 03:35:01 +00:00
gr_ubitmap012m( x, y, bm );
return;
}
} else {
2014-12-02 03:35:01 +00:00
gr_ubitmapGENERICm(x, y, bm);
}
}
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
{
//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 --;)
{
gr_linear_movsd( sbits, dbits, w );
//memcpy(dbits, sbits, w);
2014-12-02 03:35:01 +00:00
sbits += src.bm_rowsize;
dbits += dstep;
}
2006-03-20 17:12:09 +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
{
//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.
{
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
{
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_LINEAR && dest.get_type() == BM_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
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_LINEAR && dest.get_type() == BM_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;
}
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_OGL && dest.get_type() == BM_LINEAR)
2006-03-20 17:12:09 +00:00
{
return;
}
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_OGL && dest.get_type() == BM_OGL)
2006-03-20 17:12:09 +00:00
{
return;
}
#endif
2015-07-25 23:10:47 +00:00
if ((src.bm_flags & BM_FLAG_RLE) && src.get_type() == BM_LINEAR)
{
2014-12-02 03:35:01 +00:00
gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest);
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
// 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;
#ifndef OGL
int sx=0, sy=0;
#endif
2006-03-20 17:12:09 +00:00
if ((dx1 >= grd_curcanv->cv_bitmap.bm_w ) || (dx2 < 0)) return;
if ((dy1 >= grd_curcanv->cv_bitmap.bm_h) || (dy2 < 0)) return;
// Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
#ifdef OGL
2014-12-02 03:35:01 +00:00
ogl_ubitmapm_cs(x, y, 0, 0, bm, -1, F1_0);
#else
if ( dx1 < 0 )
{
sx = -dx1;
dx1 = 0;
}
if ( dy1 < 0 )
{
sy = -dy1;
dy1 = 0;
}
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; }
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 );
#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; }
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; }
2006-03-20 17:12:09 +00:00
// Draw bitmap bm[x,y] into (dx1,dy1)-(dx2,dy2)
2015-07-25 23:10:47 +00:00
if (bm.get_type() == BM_LINEAR && grd_curcanv->cv_bitmap.get_type() == BM_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
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_LINEAR && dest.get_type() == BM_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;
}
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_OGL && dest.get_type() == BM_LINEAR)
2006-03-20 17:12:09 +00:00
{
return;
}
2015-07-25 23:10:47 +00:00
if (src.get_type() == BM_OGL && dest.get_type() == BM_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 );
}
2015-12-04 03:36:31 +00:00
#endif
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)
{
int data_offset;
data_offset = 1;
2014-11-30 22:09:19 +00:00
if (src.bm_flags & BM_FLAG_RLE_BIG)
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)
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];
// No interlacing, copy the whole buffer.
2014-12-05 03:31:07 +00:00
for (uint_fast32_t i = 0; i != h; ++i)
{
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)]);
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;
}
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)
{
int data_offset;
data_offset = 1;
2014-11-30 22:09:22 +00:00
if (src.bm_flags & BM_FLAG_RLE_BIG)
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)
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];
// No interlacing, copy the whole buffer.
2014-12-05 03:31:07 +00:00
for (uint_fast32_t i = 0; i != h; ++i)
{
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)]);
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;
}
}
// 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)
{
int data_offset;
data_offset = 1;
2014-11-30 22:09:22 +00:00
if (src.bm_flags & BM_FLAG_RLE_BIG)
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)
sbits += src.bm_data[4 + (i * data_offset)];
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)]);
else
2014-11-30 22:09:22 +00:00
sbits += (int)src.bm_data[4+y1+sy];
}
}
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
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
{
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;
++i;
2006-03-20 17:12:09 +00:00
}
auto e = out + i;
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;
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) {
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
2015-07-25 23:10:47 +00:00
if (bm.get_type() == BM_LINEAR && scr.get_type() == BM_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
{
2014-12-02 03:35:01 +00:00
ogl_ubitmapm_cs(0,0,-1,-1,bm,-1,F1_0);//use opengl to scale, faster and saves ram. -MPM
2006-03-20 17:12:09 +00:00
return;
}
#endif
2015-07-25 23:10:47 +00:00
if (scr.get_type() != BM_LINEAR)
{
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
}
// Find transparent area in bitmap
void gr_bitblt_find_transparent_area(const grs_bitmap &bm, unsigned &minx, unsigned &miny, unsigned &maxx, unsigned &maxy)
{
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;
if (!(bm.bm_flags&BM_FLAG_TRANSPARENT))
return;
minx = bm.bm_w - 1;
2014-07-01 00:23:30 +00:00
maxx = 0;
miny = bm.bm_h - 1;
2014-07-01 00:23:30 +00:00
maxy = 0;
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);
}
};
// 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;
if (bm.bm_flags & BM_FLAG_RLE){
2014-07-01 02:30:39 +00:00
unsigned data_offset;
data_offset = 1;
if (bm.bm_flags & BM_FLAG_RLE_BIG)
data_offset = 2;
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;
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]);
}
}
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)
check(x, y, bm.bm_data[i++]);
}
Assert (count);
}
2015-12-05 22:57:23 +00:00
}