96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
/* ************************************************************************** */
|
|
/* _____ _ */
|
|
/* ML_bmp.c |_ _|__ _ _| |__ ___ _ _ */
|
|
/* | Project : libmonochrome | |/ _ \| | | | '_ \ / _ \ | | | */
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
|
/* Last updated: 2016/05/29 01:55:54 |___/ */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include <monochrome/internals.h>
|
|
|
|
static inline void ML_bmp_line(unsigned char *vram, const unsigned char *b,
|
|
int width, int offset, ML_Mode mode);
|
|
static inline void ML_bmp_byte(unsigned char *v, int b, int offset, int width,
|
|
ML_Mode mode);
|
|
|
|
void ML_bmp(const void *bmp, int x, int y, int width, int height, ML_Mode mode)
|
|
{
|
|
/* FIXME: no support for non-clipping blit. */
|
|
/* Oh, and yeah : most of this code is adapted from Caphics.
|
|
Clipping is, of course, on by default, and this function is not
|
|
optimized for when its disabled. */
|
|
|
|
if (x < width + 1 || x >= 128 || y < height + 1 || y >= 64)
|
|
return ;
|
|
// check clipping for retrocompatibility ?
|
|
|
|
int ls = (width >> 3) + ((width & 7) != 0); // line size
|
|
const unsigned char *b = (const unsigned char*)bmp;
|
|
|
|
// pass first lines
|
|
if (y < 0) {
|
|
b += -y * ls;
|
|
height += y;
|
|
y = 0;
|
|
}
|
|
if (height > 64 - y)
|
|
height = 64 - y;
|
|
|
|
// pass first pixels if x < 0
|
|
int offset = 0;
|
|
if (x < 0) {
|
|
b += -x >> 3;
|
|
width += x & 8;
|
|
x = 0;
|
|
}
|
|
if (width > 128 - x)
|
|
width = 128 - x;
|
|
|
|
// go to first interesting byte of vram
|
|
char *vram = ML_vram_xy(x, y);
|
|
|
|
// then draw
|
|
while (height--) {
|
|
ML_bmp_line((unsigned char*)vram, b, width, offset, mode);
|
|
vram += 8, bmp += ls;
|
|
}
|
|
}
|
|
|
|
static inline void ML_bmp_line(unsigned char *vram, const unsigned char *b,
|
|
int width, int offset, ML_Mode mode)
|
|
{
|
|
while (1) {
|
|
ML_bmp_byte(vram, *b, offset, width, mode);
|
|
if (width < 8)
|
|
break ;
|
|
vram++, b++;
|
|
width -= 8;
|
|
}
|
|
}
|
|
|
|
static inline void ML_bmp_byte(unsigned char *v, int b, int offset, int width,
|
|
ML_Mode mode)
|
|
{
|
|
if (width < 8) b &= 255 << (8 - width);
|
|
|
|
switch (mode) {
|
|
case ML_MAND:
|
|
*v &= ~(b >> offset);
|
|
if (width > 8 - offset)
|
|
*(++v) &= ~(b << (8 - offset));
|
|
break;
|
|
case ML_MOR:
|
|
*v |= b >> offset;
|
|
if (width > 8 - offset)
|
|
*(++v) |= b << (8 - offset);
|
|
break;
|
|
case ML_MXOR:
|
|
*v ^= b >> offset;
|
|
if (width > 8 - offset)
|
|
*(++v) ^= b << (8 - offset);
|
|
break;
|
|
}
|
|
}
|