Initial commit
This commit is contained in:
912
engines/qdengine/system/graphics/gr_draw_sprite_rle.cpp
Normal file
912
engines/qdengine/system/graphics/gr_draw_sprite_rle.cpp
Normal file
@@ -0,0 +1,912 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/textconsole.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
#include "qdengine/qdengine.h"
|
||||
#include "qdengine/qd_fwd.h"
|
||||
#include "qdengine/system/graphics/gr_dispatcher.h"
|
||||
#include "qdengine/system/graphics/rle_compress.h"
|
||||
|
||||
|
||||
namespace QDEngine {
|
||||
|
||||
void grDispatcher::putSpr_rle(int x, int y, int sx, int sy, const class RLEBuffer *p, int mode, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle([%d, %d], [%d, %d], mode: %d, alpha: %d", x, y, sx, sy, mode, alpha_flag);
|
||||
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if (!clip_rectangle(x, y, px, py, psx, psy)) return;
|
||||
int dx = -2;
|
||||
int dy = -1;
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x += (psx - 1);
|
||||
px = sx - px - psx;
|
||||
} else
|
||||
dx = 2;
|
||||
|
||||
if (_pixel_format == GR_RGBA8888)
|
||||
dx *= 2;
|
||||
|
||||
psx += px;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
} else
|
||||
dy = 1;
|
||||
|
||||
for (int i = 0; i < psy; i++) {
|
||||
byte *scr_buf = reinterpret_cast<byte *>(_screenBuf->getBasePtr(x, y));
|
||||
|
||||
const int8 *rle_header = p->header_ptr(py + i);
|
||||
const uint32 *rle_data = p->data_ptr(py + i);
|
||||
|
||||
int j = 0;
|
||||
int8 count = 0;
|
||||
while (j < px) {
|
||||
count = *rle_header++;
|
||||
if (count > 0) {
|
||||
if (count + j <= px) {
|
||||
j += count;
|
||||
rle_data++;
|
||||
count = 0;
|
||||
} else {
|
||||
count -= px - j;
|
||||
j = px;
|
||||
}
|
||||
} else {
|
||||
if (j - count <= px) {
|
||||
j -= count;
|
||||
rle_data -= count;
|
||||
count = 0;
|
||||
} else {
|
||||
count += px - j;
|
||||
rle_data += px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!alpha_flag) {
|
||||
while (j < psx) {
|
||||
if (count > 0) {
|
||||
while (count && j < psx) {
|
||||
if (*rle_data) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 cl = make_rgb(rle_buf[2], rle_buf[1], rle_buf[0]);
|
||||
setPixelFast(scr_buf, cl);
|
||||
}
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
} else {
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
while (count && j < psx) {
|
||||
if (*rle_data) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 cl = make_rgb(rle_buf[2], rle_buf[1], rle_buf[0]);
|
||||
setPixelFast(scr_buf, cl);
|
||||
}
|
||||
scr_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
} else {
|
||||
while (j < psx) {
|
||||
if (count > 0) {
|
||||
while (count && j < psx) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 a = rle_buf[3];
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
*(uint16 *)scr_buf = alpha_blend_565(make_rgb565u(rle_buf[2], rle_buf[1], rle_buf[0]), *(uint16 *)scr_buf, a);
|
||||
} else {
|
||||
if (a != 255) {
|
||||
scr_buf[1] = rle_buf[0] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = rle_buf[1] + ((a * scr_buf[2]) >> 8);
|
||||
scr_buf[3] = rle_buf[2] + ((a * scr_buf[3]) >> 8);
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
} else {
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
while (count && j < psx) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 a = rle_buf[3];
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
*(uint16 *)scr_buf = alpha_blend_565(make_rgb565u(rle_buf[2], rle_buf[1], rle_buf[0]), *(uint16 *)scr_buf, a);
|
||||
} else {
|
||||
if (a != 255) {
|
||||
scr_buf[1] = rle_buf[0] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = rle_buf[1] + ((a * scr_buf[2]) >> 8);
|
||||
scr_buf[3] = rle_buf[2] + ((a * scr_buf[3]) >> 8);
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::putSpr_rle(int x, int y, int sx, int sy, const class RLEBuffer *p, int mode, float scale, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle([%d, %d], [%d, %d], mode: %d, scale: %f, alpha: %d", x, y, sx, sy, mode, scale, alpha_flag);
|
||||
|
||||
int sx_dest = round(float(sx) * scale);
|
||||
int sy_dest = round(float(sy) * scale);
|
||||
|
||||
if (sx_dest <= 0 || sy_dest <= 0) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest - 1;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest - 1;
|
||||
int iy = 1;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y0 = sy_dest - 1,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x0 = sx_dest - 1,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
if (!alpha_flag) {
|
||||
const byte *line_src = RLEBuffer::get_buffer(0);
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
const byte *src_data = line_src + (fx >> 16) * 3;
|
||||
if (src_data[0] || src_data[1] || src_data[2])
|
||||
setPixelFast(x + j, y + i, make_rgb(src_data[2], src_data[1], src_data[0]));
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const byte *line_src = RLEBuffer::get_buffer(0);
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
const byte *src_data = line_src + ((fx >> 16) << 2);
|
||||
|
||||
uint32 a = src_data[3];
|
||||
if (a != 255) {
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
uint32 cl = make_rgb565u(src_data[2], src_data[1], src_data[0]);
|
||||
|
||||
if (a) {
|
||||
uint16 scl;
|
||||
getPixel(x + j, y + i, scl);
|
||||
|
||||
setPixelFast(x + j, y + i, alpha_blend_565(cl, scl, a));
|
||||
} else
|
||||
setPixelFast(x + j, y + i, cl);
|
||||
} else {
|
||||
byte sr, sg, sb;
|
||||
getPixel(x + j, y + i, sr, sg, sb);
|
||||
|
||||
uint32 r = src_data[2] + ((a * sr) >> 8);
|
||||
uint32 g = src_data[1] + ((a * sg) >> 8);
|
||||
uint32 b = src_data[0] + ((a * sb) >> 8);
|
||||
|
||||
setPixelFast(x + j, y + i, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::putSprMask_rle(int x, int y, int sx, int sy, const RLEBuffer *p, uint32 mask_color, int mask_alpha, int mode, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSprMask_rle([%d, %d], [%d, %d], ...)", x, y, sx, sy);
|
||||
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if (!clip_rectangle(x, y, px, py, psx, psy)) return;
|
||||
|
||||
int dx = -2;
|
||||
int dy = -1;
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x += (psx - 1);
|
||||
px = sx - px - psx;
|
||||
} else
|
||||
dx = 2;
|
||||
|
||||
if (_pixel_format == GR_RGBA8888)
|
||||
dx *= 2;
|
||||
|
||||
psx += px;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
} else
|
||||
dy = 1;
|
||||
|
||||
for (int i = 0; i < psy; i++) {
|
||||
byte *scr_buf = reinterpret_cast<byte *>(_screenBuf->getBasePtr(x, y));
|
||||
|
||||
const int8 *rle_header = p->header_ptr(py + i);
|
||||
const uint32 *rle_data = p->data_ptr(py + i);
|
||||
|
||||
int j = 0;
|
||||
int8 count = 0;
|
||||
while (j < px) {
|
||||
count = *rle_header++;
|
||||
if (count > 0) {
|
||||
if (count + j <= px) {
|
||||
j += count;
|
||||
rle_data++;
|
||||
count = 0;
|
||||
} else {
|
||||
count -= px - j;
|
||||
j = px;
|
||||
}
|
||||
} else {
|
||||
if (j - count <= px) {
|
||||
j -= count;
|
||||
rle_data -= count;
|
||||
count = 0;
|
||||
} else {
|
||||
count += px - j;
|
||||
rle_data += px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
byte mr, mg, mb;
|
||||
if (_pixel_format == GR_RGB565)
|
||||
split_rgb565u(mask_color, mr, mg, mb);
|
||||
else
|
||||
split_rgb888(mask_color, mr, mg, mb);
|
||||
|
||||
if (!alpha_flag) {
|
||||
mr = (mr * (255 - mask_alpha)) >> 8;
|
||||
mg = (mg * (255 - mask_alpha)) >> 8;
|
||||
mb = (mb * (255 - mask_alpha)) >> 8;
|
||||
|
||||
uint32 cl = make_rgb(mr, mg, mb);
|
||||
|
||||
while (j < psx) {
|
||||
if (count > 0) {
|
||||
while (count && j < psx) {
|
||||
if (*rle_data) {
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
setPixelFast(scr_buf, cl);
|
||||
} else {
|
||||
scr_buf[3] = mr + ((mask_alpha * scr_buf[3]) >> 8);
|
||||
scr_buf[2] = mg + ((mask_alpha * scr_buf[2]) >> 8);
|
||||
scr_buf[1] = mb + ((mask_alpha * scr_buf[1]) >> 8);
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
} else {
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
while (count && j < psx) {
|
||||
if (*rle_data) {
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
setPixelFast(scr_buf, cl);
|
||||
} else {
|
||||
scr_buf[3] = mr + ((mask_alpha * scr_buf[3]) >> 8);
|
||||
scr_buf[2] = mg + ((mask_alpha * scr_buf[2]) >> 8);
|
||||
scr_buf[1] = mb + ((mask_alpha * scr_buf[1]) >> 8);
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
} else {
|
||||
while (j < psx) {
|
||||
if (count > 0) {
|
||||
while (count && j < psx) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 a = rle_buf[3];
|
||||
|
||||
if (a != 255) {
|
||||
a = mask_alpha + ((a * (255 - mask_alpha)) >> 8);
|
||||
|
||||
uint32 r = (mr * (255 - a)) >> 8;
|
||||
uint32 g = (mg * (255 - a)) >> 8;
|
||||
uint32 b = (mb * (255 - a)) >> 8;
|
||||
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
uint16 cl = make_rgb565u(r, g, b);
|
||||
*(uint16 *)scr_buf = alpha_blend_565(cl, *(uint16 *)scr_buf, a);
|
||||
} else {
|
||||
scr_buf[1] = b + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = g + ((a * scr_buf[2]) >> 8);
|
||||
scr_buf[3] = r + ((a * scr_buf[3]) >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
} else {
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
while (count && j < psx) {
|
||||
const byte *rle_buf = (const byte *)rle_data;
|
||||
uint32 a = rle_buf[3];
|
||||
|
||||
if (a != 255) {
|
||||
a = mask_alpha + ((a * (255 - mask_alpha)) >> 8);
|
||||
|
||||
uint32 r = (mr * (255 - a)) >> 8;
|
||||
uint32 g = (mg * (255 - a)) >> 8;
|
||||
uint32 b = (mb * (255 - a)) >> 8;
|
||||
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
uint16 cl = make_rgb565u(r, g, b);
|
||||
*(uint16 *)scr_buf = alpha_blend_565(cl, *(uint16 *)scr_buf, a);
|
||||
} else {
|
||||
scr_buf[1] = b + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = g + ((a * scr_buf[2]) >> 8);
|
||||
scr_buf[3] = r + ((a * scr_buf[3]) >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
scr_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::putSprMask_rle(int x, int y, int sx, int sy, const RLEBuffer *p, uint32 mask_color, int mask_alpha, int mode, float scale, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSprMask_rle([%d, %d], [%d, %d], mask: %d, alpha: %d, mode: %d, scale: %f, alpha_flag: %d)", x, y, sx, sy, mask_color, mask_alpha, mode, scale, alpha_flag);
|
||||
|
||||
int sx_dest = round(float(sx) * scale);
|
||||
int sy_dest = round(float(sy) * scale);
|
||||
|
||||
if (sx_dest <= 0 || sy_dest <= 0) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest - 1;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest - 1;
|
||||
int iy = 1;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y0 = sy_dest - 1,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x0 = sx_dest - 1,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
if (!alpha_flag) {
|
||||
byte mr, mg, mb;
|
||||
if (_pixel_format == GR_RGB565)
|
||||
split_rgb565u(mask_color, mr, mg, mb);
|
||||
else
|
||||
split_rgb888(mask_color, mr, mg, mb);
|
||||
|
||||
mr = (mr * (255 - mask_alpha)) >> 8;
|
||||
mg = (mg * (255 - mask_alpha)) >> 8;
|
||||
mb = (mb * (255 - mask_alpha)) >> 8;
|
||||
|
||||
uint32 mcl = make_rgb(mr, mg, mb);
|
||||
|
||||
const byte *line_src = RLEBuffer::get_buffer(0);
|
||||
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
const byte *src_buf = line_src + ((fx >> 16) << 2);
|
||||
if (src_buf[0] || src_buf[1] || src_buf[2]) {
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
uint16 scl;
|
||||
getPixel(x + j, y + i, scl);
|
||||
setPixelFast(x + j, y + i, alpha_blend_565(mcl, scl, mask_alpha));
|
||||
} else {
|
||||
byte sr, sg, sb;
|
||||
getPixel(x + j, y + i, sr, sg, sb);
|
||||
|
||||
uint32 r = mr + ((mask_alpha * sr) >> 8);
|
||||
uint32 g = mg + ((mask_alpha * sg) >> 8);
|
||||
uint32 b = mb + ((mask_alpha * sb) >> 8);
|
||||
|
||||
setPixelFast(x + j, y + i, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const byte *line_src = RLEBuffer::get_buffer(0);
|
||||
byte mr, mg, mb;
|
||||
if (_pixel_format == GR_RGB565)
|
||||
split_rgb565u(mask_color, mr, mg, mb);
|
||||
else
|
||||
split_rgb888(mask_color, mr, mg, mb);
|
||||
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
const byte *src_buf = line_src + ((fx >> 16) << 2);
|
||||
uint32 a = src_buf[3];
|
||||
if (a != 255) {
|
||||
a = mask_alpha + ((a * (255 - mask_alpha)) >> 8);
|
||||
|
||||
uint32 r = (mr * (255 - a)) >> 8;
|
||||
uint32 g = (mg * (255 - a)) >> 8;
|
||||
uint32 b = (mb * (255 - a)) >> 8;
|
||||
|
||||
if (_pixel_format == GR_RGB565) {
|
||||
uint16 scl;
|
||||
getPixel(x + j, y + i, scl);
|
||||
|
||||
uint16 cl = make_rgb565u(r, g, b);
|
||||
setPixelFast(x + j, y + i, alpha_blend_565(cl, scl, a));
|
||||
} else {
|
||||
byte sr, sg, sb;
|
||||
getPixel(x + j, y + i, sr, sg, sb);
|
||||
|
||||
r = r + ((a * sr) >> 8);
|
||||
g = g + ((a * sg) >> 8);
|
||||
b = b + ((a * sb) >> 8);
|
||||
|
||||
setPixelFast(x + j, y + i, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle_rot([%d, %d], [%d, %d], alpha: %d, mode: %d, angle: %f", pos.x, pos.y, size.x, size.y, has_alpha, mode, angle);
|
||||
|
||||
byte *buf = (byte *)temp_buffer(size.x * size.y * 4);
|
||||
|
||||
byte *buf_ptr = buf;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
data->decode_line(i, buf_ptr);
|
||||
buf_ptr += size.x * 4;
|
||||
}
|
||||
|
||||
if (!has_alpha) {
|
||||
uint32 *p = (uint32 *)buf;
|
||||
buf_ptr = buf + 3;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
for (int j = 0; j < size.x; j++) {
|
||||
if (!*p++)
|
||||
*buf_ptr = 255;
|
||||
|
||||
buf_ptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putSpr_rot(pos, size, buf, true, mode, angle);
|
||||
}
|
||||
|
||||
void grDispatcher::putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle, const Vect2f &scale) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle_rot([%d, %d], [%d, %d], alpha: %d, mode: %d, angle: %f, scale: [%f, %f]", pos.x, pos.y, size.x, size.y, has_alpha, mode, angle, scale.x, scale.y);
|
||||
|
||||
byte *buf = (byte *)temp_buffer(size.x * size.y * 4);
|
||||
|
||||
byte *buf_ptr = buf;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
data->decode_line(i, buf_ptr);
|
||||
buf_ptr += size.x * 4;
|
||||
}
|
||||
|
||||
if (!has_alpha) {
|
||||
uint32 *p = (uint32 *)buf;
|
||||
buf_ptr = buf + 3;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
for (int j = 0; j < size.x; j++) {
|
||||
if (!*p++)
|
||||
*buf_ptr = 255;
|
||||
|
||||
buf_ptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putSpr_rot(pos, size, buf, true, mode, angle, scale);
|
||||
}
|
||||
|
||||
void grDispatcher::putSprMask_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle_rot([%d, %d], [%d, %d], alpha: %d, mask: %d, mask_alpha: %d, mode: %d, angle: %f", pos.x, pos.y, size.x, size.y, has_alpha, mask_color, mask_alpha, mode, angle);
|
||||
|
||||
byte *buf = (byte *)temp_buffer(size.x * size.y * 4);
|
||||
|
||||
byte *buf_ptr = buf;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
data->decode_line(i, buf_ptr);
|
||||
buf_ptr += size.x * 4;
|
||||
}
|
||||
|
||||
if (!has_alpha) {
|
||||
uint32 *p = (uint32 *)buf;
|
||||
buf_ptr = buf + 3;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
for (int j = 0; j < size.x; j++) {
|
||||
if (!*p++)
|
||||
*buf_ptr = 255;
|
||||
|
||||
buf_ptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putSprMask_rot(pos, size, buf, true, mask_color, mask_alpha, mode, angle);
|
||||
}
|
||||
|
||||
void grDispatcher::putSprMask_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle, const Vect2f &scale) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::putSpr_rle_rot([%d, %d], [%d, %d], alpha: %d, mask: %d, mask_alpha: %d, mode: %d, angle: %f, scale: [%f, %f]", pos.x, pos.y, size.x, size.y, has_alpha, mask_color, mask_alpha, mode, angle, scale.x, scale.y);
|
||||
|
||||
byte *buf = (byte *)temp_buffer(size.x * size.y * 4);
|
||||
|
||||
byte *buf_ptr = buf;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
data->decode_line(i, buf_ptr);
|
||||
buf_ptr += size.x * 4;
|
||||
}
|
||||
|
||||
if (!has_alpha) {
|
||||
uint32 *p = (uint32 *)buf;
|
||||
buf_ptr = buf + 3;
|
||||
for (int i = 0; i < size.y; i++) {
|
||||
for (int j = 0; j < size.x; j++) {
|
||||
if (!*p++)
|
||||
*buf_ptr = 255;
|
||||
|
||||
buf_ptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
putSprMask_rot(pos, size, buf, true, mask_color, mask_alpha, mode, angle, scale);
|
||||
}
|
||||
|
||||
inline bool rle_alpha_b(uint32 pixel) {
|
||||
return (reinterpret_cast<byte *>(&pixel)[3] < 200);
|
||||
}
|
||||
inline bool rle_alpha_b16(uint16 pixel) {
|
||||
return pixel < 200;
|
||||
}
|
||||
|
||||
void grDispatcher::drawSprContour(int x, int y, int sx, int sy, const class RLEBuffer *p, int contour_color, int mode, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::drawSprContour([%d, %d], [%d, %d], contour_color: %d, mode: %d, alpha_flag: %d)", x, y, sx, sy, contour_color, mode, alpha_flag);
|
||||
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if (!clip_rectangle(x, y, px, py, psx, psy)) return;
|
||||
int dx = -1;
|
||||
int dy = -1;
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x += (psx - 1) * 2;
|
||||
px = sx - px - psx;
|
||||
} else
|
||||
dx = 1;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
} else
|
||||
dy = 1;
|
||||
|
||||
const uint16 *data0 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(0));
|
||||
const uint16 *data1 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(1));
|
||||
|
||||
px <<= 1;
|
||||
psx <<= 1;
|
||||
|
||||
warning("STUB: grDispatcher::drawSprContour");
|
||||
for (int i = 0; i < psy; i++) {
|
||||
uint16 *scr_buf = (uint16 *)_screenBuf->getBasePtr(x, y);
|
||||
uint16 *scr_buf_prev = (i) ? (uint16 *)_screenBuf->getBasePtr(x, y - dy) : scr_buf;
|
||||
p->decode_line(py + i, i & 1);
|
||||
|
||||
const uint16 *data_ptr = (i & 1) ? data1 + px : data0 + px;
|
||||
const uint16 *data_ptr_prev = (i & 1) ? data0 + px : data1 + px;
|
||||
|
||||
if (!alpha_flag) {
|
||||
uint32 pixel = 0;
|
||||
for (int j = 0; j < psx; j += 2) {
|
||||
pixel = data_ptr[j];
|
||||
|
||||
if (!pixel && j && data_ptr[j - 2]) {
|
||||
*(scr_buf - dx) = contour_color;
|
||||
}
|
||||
if ((pixel && (!j || !data_ptr[j - 2]))) {
|
||||
*scr_buf = contour_color;
|
||||
} else {
|
||||
if (pixel && (!i || !data_ptr_prev[j])) {
|
||||
*scr_buf = contour_color;
|
||||
}
|
||||
}
|
||||
if (!pixel && i && data_ptr_prev[j]) {
|
||||
*scr_buf_prev = contour_color;
|
||||
}
|
||||
|
||||
scr_buf += dx;
|
||||
scr_buf_prev += dx;
|
||||
}
|
||||
if (pixel) *(scr_buf - dx) = contour_color;
|
||||
} else {
|
||||
bool pixel = false;
|
||||
for (int j = 0; j < psx; j += 2) {
|
||||
pixel = rle_alpha_b16(data_ptr[j + 1]);
|
||||
|
||||
if (!pixel && j && rle_alpha_b16(data_ptr[j - 1])) {
|
||||
*(scr_buf - dx) = contour_color;
|
||||
}
|
||||
if ((pixel && (!j || !rle_alpha_b16(data_ptr[j - 1])))) {
|
||||
*scr_buf = contour_color;
|
||||
} else {
|
||||
if (pixel && (!i || !rle_alpha_b16(data_ptr_prev[j + 1]))) {
|
||||
*scr_buf = contour_color;
|
||||
}
|
||||
}
|
||||
if (!pixel && i && rle_alpha_b16(data_ptr_prev[j + 1])) {
|
||||
*scr_buf_prev = contour_color;
|
||||
}
|
||||
|
||||
scr_buf += dx;
|
||||
scr_buf_prev += dx;
|
||||
}
|
||||
if (pixel) *(scr_buf - dx) = contour_color;
|
||||
}
|
||||
|
||||
y += dy;
|
||||
}
|
||||
uint16 *scr_buf_prev = (uint16 *)_screenBuf->getBasePtr(x, y - dy);
|
||||
const uint16 *data_ptr_prev = (psy & 1) ? data0 + px : data1 + px;
|
||||
if (!alpha_flag) {
|
||||
for (int j = 0; j < psx; j += 2) {
|
||||
if (data_ptr_prev[j])
|
||||
*scr_buf_prev = contour_color;
|
||||
scr_buf_prev += dx;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < psx; j += 2) {
|
||||
if (rle_alpha_b16(data_ptr_prev[j + 1]))
|
||||
*scr_buf_prev = contour_color;
|
||||
scr_buf_prev += dx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void grDispatcher::drawSprContour(int x, int y, int sx, int sy, const class RLEBuffer *p, int contour_color, int mode, float scale, bool alpha_flag) {
|
||||
debugC(4, kDebugGraphics, "grDispatcher::drawSprContour([%d, %d], [%d, %d], contour_color: %d, mode: %d, scale: %f, alpha_flag: %d)", x, y, sx, sy, contour_color, mode, scale, alpha_flag);
|
||||
|
||||
int sx_dest = round(float(sx) * scale);
|
||||
int sy_dest = round(float(sy) * scale);
|
||||
|
||||
if (!sx_dest || !sy_dest) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest;
|
||||
int iy = 1;
|
||||
|
||||
if (mode & GR_FLIP_VERTICAL) {
|
||||
y0 = sy_dest,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if (mode & GR_FLIP_HORIZONTAL) {
|
||||
x0 = sx_dest,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
|
||||
if (!alpha_flag) {
|
||||
const uint16 *line0 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(0));
|
||||
const uint16 *line1 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(1));
|
||||
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16, i & 1);
|
||||
const uint16 *line_src = (i & 1) ? line1 : line0;
|
||||
const uint16 *line_src_prev = (i & 1) ? line0 : line1;
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
uint32 cl = 0;
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
cl = line_src[(fx >> 16) << 1];
|
||||
if (!cl && j != x0 && line_src[((fx - dx) >> 16) << 1])
|
||||
setPixel(x + j - ix, y + i, contour_color);
|
||||
|
||||
if (cl && (j == x0 || !line_src[((fx - dx) >> 16) << 1])) {
|
||||
setPixelFast(x + j, y + i, contour_color);
|
||||
} else {
|
||||
if (cl && (i == y0 || !line_src_prev[(fx >> 16) << 1]))
|
||||
setPixelFast(x + j, y + i, contour_color);
|
||||
}
|
||||
|
||||
if (!cl && i != y0 && line_src_prev[(fx >> 16) << 1])
|
||||
setPixel(x + j, y + i - iy, contour_color);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
if (cl) setPixel(x + x1 - ix, y + i, contour_color);
|
||||
}
|
||||
fx = (1 << 15);
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
const uint16 *line_src_prev = (y1 & 1) ? line0 : line1;
|
||||
if (line_src_prev[(fx >> 16) << 1])
|
||||
setPixel(x + j, y + y1 - iy, contour_color);
|
||||
fx += dx;
|
||||
}
|
||||
} else {
|
||||
const uint16 *line0 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(0));
|
||||
const uint16 *line1 = reinterpret_cast<const uint16 *>(RLEBuffer::get_buffer(1));
|
||||
|
||||
for (int i = y0; i != y1; i += iy) {
|
||||
p->decode_line(fy >> 16, i & 1);
|
||||
const uint16 *line_src = (i & 1) ? line1 : line0;
|
||||
const uint16 *line_src_prev = (i & 1) ? line0 : line1;
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
bool cl = false;
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
if (clipCheck(x + j, y + i)) {
|
||||
cl = rle_alpha_b16(line_src[((fx >> 16) << 1) + 1]);
|
||||
if (!cl && j != x0 && rle_alpha_b16(line_src[(((fx - dx) >> 16) << 1) + 1]))
|
||||
setPixel(x + j - ix, y + i, contour_color);
|
||||
|
||||
if (cl && (j == x0 || !rle_alpha_b16(line_src[(((fx - dx) >> 16) << 1) + 1]))) {
|
||||
setPixelFast(x + j, y + i, contour_color);
|
||||
} else {
|
||||
if (cl && (i == y0 || !rle_alpha_b16(line_src_prev[((fx >> 16) << 1) + 1])))
|
||||
setPixelFast(x + j, y + i, contour_color);
|
||||
}
|
||||
|
||||
if (!cl && i != y0 && rle_alpha_b16(line_src_prev[((fx >> 16) << 1) + 1]))
|
||||
setPixel(x + j, y + i - iy, contour_color);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
if (cl) setPixel(x + x1 - ix, y + i, contour_color);
|
||||
}
|
||||
fx = (1 << 15);
|
||||
for (int j = x0; j != x1; j += ix) {
|
||||
const uint16 *line_src_prev = (y1 & 1) ? line0 : line1;
|
||||
if (rle_alpha_b16(line_src_prev[((fx >> 16) << 1) + 1]))
|
||||
setPixel(x + j, y + y1 - iy, contour_color);
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QDEngine
|
||||
Reference in New Issue
Block a user