#include "mkhiblib.h" /** * Copy a screen in an other * * @param dst the destination screen * @param src the source screen */ void hl_screenCopy(h_Screen dst, h_Screen src) { short h = src.size.height - src.pos.y; if (h > dst.size.height - dst.pos.y) { h = dst.size.height - dst.pos.y; } if (src.mem.byte_width == 0) { src.mem.byte_width = ((src.size.width + 7) >> 3); } if (dst.mem.byte_width == 0) { dst.mem.byte_width = ((dst.size.width + 7) >> 3); } short j = 0; short dst_x_; short byte_width = src.mem.byte_width; unsigned char * s = src.mem.ptr + src.pos.y * src.mem.byte_width; short out_right = 0; if (((byte_width << 3) - src.pos.x) >= dst.size.width) { out_right = (((byte_width << 3) - src.pos.x - dst.size.width) >> 3); byte_width -= out_right; } short out_left = 0; if (src.pos.x > 0) { out_left = (src.pos.x >> 3); byte_width -= out_left; } short offset = (dst.pos.x & 7) - (src.pos.x & 7); dst_x_ = dst.pos.x; if (offset < 0) { dst_x_--; offset += 8; } if (byte_width < 0) { byte_width = 0; } dst.mem.ptr += dst.pos.y * dst.mem.byte_width + (dst_x_ >> 3); for (j = 0; j < h; j++) { short x_ = dst_x_; unsigned char * d = dst.mem.ptr; short n = byte_width; s += out_left; if (x_ >= dst.pos.x) { (*d) |= ((*s) >> (offset)); } d++; while (n > 1) { (*d) |= ((*s) << (8 - offset)); s++; (*d) |= ((*s) >> (offset)); d++; x_ += 8; n--; } if (x_ <= dst.size.width + dst.pos.x - 8) { (*d) |= ((*s) << (8 - offset)); } s++; s += out_right; dst.mem.ptr += dst.mem.byte_width; } } /** * Draw an vertical line * This function assumes that y1 < y2 * * @param x the x position in the screen * @param y1 the starting pixel * @param y2 the last pixel * @param mode the mode of drawing * @param screen the screen to draw in */ void hl_drawLineVert(short x, short y1, short y2, short mode, h_ScreenMem screen) { screen.ptr += y1 * screen.byte_width + (x >> 3); unsigned char * p = screen.ptr; short pix = ((0x80) >> (x & 0x07)); y2 -= y1 - 1; while (y2 != 0) { switch (mode) { case HGRAPHMODE_BLACK: *p |= pix; break; case HGRAPHMODE_WHITE: *p &= ~pix; break; case HGRAPHMODE_INVERSED: *p ^= pix; break; } p += screen.byte_width; y2--; } } /** * Fill a frame with the specied color * This function assumes that x1 < x2 and y1 < y2 * * @param x1 the x position of the starting pixel * @param x2 the x position of the last pixel * @param y1 the y position of the starting pixel * @param y2 the y position of the last pixel * @param mode the mode of drawing * @param screen the screen to draw in */ void hl_fillFrame(short x1, short y1, short x2, short y2, short mode, h_ScreenMem screen) { short offset1 = x1 & 7; short mask1 = (0xFF >> offset1); short offset2 = 7 - (x2 & 7); short mask2 = (0xFF << offset2); short j; unsigned char * dst; screen.ptr += y1 * screen.byte_width + (x1 >> 3); x1 = (x2 - x1 + 1 + offset1 + offset2) / 8 - (offset1 != 0) - (offset2 != 0); y2 -= y1 - 1; if (x1 < 0) { mask1 &= mask2; } while (y2 != 0) { dst = screen.ptr; if (offset1 != 0 || x1 < 0) { switch (mode) { case HGRAPHMODE_BLACK: *(dst++) |= mask1; break; case HGRAPHMODE_WHITE: *(dst++) &= ~mask1; break; case HGRAPHMODE_INVERSED: *(dst++) ^= mask1; break; } } for (j = 0; j < x1; j++) { switch (mode) { case HGRAPHMODE_BLACK: *(dst++) = 0xFF; break; case HGRAPHMODE_WHITE: *(dst++) = 0x00; break; case HGRAPHMODE_INVERSED: *(dst++) ^= 0xFF; break; } } if (offset2 != 0 && x1 >= 0) { switch (mode) { case HGRAPHMODE_BLACK: *dst |= mask2; break; case HGRAPHMODE_WHITE: *dst &= ~mask2; break; case HGRAPHMODE_INVERSED: *dst ^= mask2; break; } } y2--; screen.ptr += screen.byte_width; } }