📄 x_sherry.c
字号:
{ if(x1 < 0 || y1 < 0 || x2 >= scr->width || y2 >= scr->height || x1 > x2 || y1 > y2) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: Out of range: (%d,%d)-(%d,%d)" " > %dx%d, stop sherring", x1, y1, x2, y2, scr->width, scr->height); err_to_stop = 1; return 0; } return 1;}static VirtualScreen *virtual_screen(int scr){ if(virtualScreen[scr] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: screen %d is not allocated, stop sherring", scr); err_to_stop = 1; return NULL; } return virtualScreen[scr];}static void copy_vscreen_area(VirtualScreen *src, VirtualScreen *dest, int src_x1, int src_y1, int src_x2, int src_y2, int dest_x, int dest_y, int mask, int trans){ int x, y, sw, dw; uint8 *source, *target; int ww, hh; sw = src->width; dw = dest->width; source = src->data; target = dest->data; ww = src_x2 - src_x1 + 1; hh = src_y2 - src_y1 + 1; if(mask == 0xff && !trans) { for(y = 0; y < hh; y++) { memcpy(target + (dest_y + y) * dw + dest_x, source + (src_y1 + y) * sw + src_x1, ww); } } else { int p, q, i; int skip_color; skip_color = trans? src->transParent : -1; for(y = 0; y < hh; y++) { for(x = 0; x < ww; x++) { p = source[(src_y1 + y) * sw + src_x1 + x]; if(p == skip_color) continue; i = (dest_y + y) * dw + dest_x + x; q = target[i]; target[i] = ROP3_CA0749(mask, p, q); } } }}static void sry_trans_partial(uint8 *data){ VirtualScreen *src, *dest; int from, to; int x1, y1, x2, y2, tx, ty; int mask, trans; from = SRY_GET_SHORT(data + 0) & 0xffff; to = SRY_GET_SHORT(data + 2) & 0xffff; mask = data[4]; trans = data[5]; x1 = SRY_GET_SHORT(data + 6) & 0xffff; y1 = SRY_GET_SHORT(data + 8) & 0xffff; x2 = SRY_GET_SHORT(data +10) & 0xffff; y2 = SRY_GET_SHORT(data +12) & 0xffff; tx = SRY_GET_SHORT(data +14) & 0xffff; ty = SRY_GET_SHORT(data +16) & 0xffff; if((src = virtual_screen(from)) == NULL) return; if((dest = virtual_screen(to)) == NULL) return;#ifdef SRY_DEBUG printf("Screen copy: %d:(%d,%d)-(%d,%d) -> %d:(%d,%d) mask=0x%02x trans=%d\n", from, x1, y1, x2, y2, to, tx, ty, mask, trans);#endif /* SRY_DEBUG */ normalize_rect(&x1, &y1, &x2, &y2); if(!check_range(src, x1, y1, x2, y2)) return; if(!check_range(dest, tx, ty, tx + x2 - x1, ty + y2 - y1)) return; if(src == dest) { VirtualScreen *tmp; tmp = get_tmp_screen(x2 + 1, y2 + 1); tmp->transParent = src->transParent; copy_vscreen_area(src, tmp, x1, y1, x2, y2, x1, y1, 0xff, 0); src = tmp; } copy_vscreen_area(src, dest, x1, y1, x2, y2, tx, ty, mask, trans);}static void sry_trans_partial_mask(uint8 *data){ int from, to; int planeMask, transparencyFlag; int x1, y1, x2, y2, toX, toY; int maskX, maskY; uint8 *maskData; VirtualScreen *src, *dest; int x, y, width, height; int mx, my; int bytesPerLine; int srcP, dstP; from = SRY_GET_SHORT(data + 0) & 0xffff; to = SRY_GET_SHORT(data + 2) & 0xffff; planeMask = data[4]; transparencyFlag = data[5]; x1 = SRY_GET_SHORT(data + 6) & 0xffff; y1 = SRY_GET_SHORT(data + 8) & 0xffff; x2 = SRY_GET_SHORT(data +10) & 0xffff; y2 = SRY_GET_SHORT(data +12) & 0xffff; toX = SRY_GET_SHORT(data +14) & 0xffff; toY = SRY_GET_SHORT(data +16) & 0xffff; maskX = data[18]; maskY = data[19]; maskData = data + 20; width = x2 - x1 + 1; height = y2 - y1 + 1; if((src = virtual_screen(from)) == NULL) return; if((dest = virtual_screen(to)) == NULL) return; normalize_rect(&x1, &y1, &x2, &y2); if(!check_range(src, x1, y1, x2, y2)) return; if(!check_range(dest, toX, toY, toX + x2 - x1, toY + y2 - y1)) return; if(src == dest) { VirtualScreen *tmp; tmp = get_tmp_screen(x2 + 1, y2 + 1); tmp->transParent = src->transParent; copy_vscreen_area(src, tmp, x1, y1, x2, y2, x1, y1, 0xff, 0); src = tmp; } bytesPerLine = maskX; bytesPerLine = ((bytesPerLine + 7) & ~7); /* round up to 8 */ bytesPerLine /= 8; my = y1 % maskY; for(y = 0; y < height; y++, my++) { if(my == maskY) my = 0; mx = x1 % maskX; for(x = 0; x < width; x++, mx++) { if(mx == maskX) mx = 0; if(maskData[my * bytesPerLine + mx / 8] & (0x80 >> (mx%8))) { srcP = VSCREEN_PIXEL(src, x1 + x, y1 + y); if(!transparencyFlag || srcP != src->transParent) { dstP = VSCREEN_PIXEL(dest, toX + x, toY + y); VSCREEN_PIXEL(dest, toX + x, toY + y) = ROP3_CA0749(planeMask, srcP, dstP); } } } }}static void sry_draw_box(uint8 *data){ int screen; int mask; int x1, y1, x2, y2, x, y; int color; VirtualScreen *v; screen = SRY_GET_SHORT(data + 0) & 0xffff; mask = data[2]; x1 = SRY_GET_SHORT(data + 3) & 0xffff; y1 = SRY_GET_SHORT(data + 5) & 0xffff; x2 = SRY_GET_SHORT(data + 7) & 0xffff; y2 = SRY_GET_SHORT(data + 9) & 0xffff; color = data[11];#ifdef SRY_DEBUG printf("Box %d 0x%02x (%d,%d)-(%d,%d)\n", screen, mask, x1, y1, x2, y2);#endif /* SRY_DEBUG */ if((v = virtual_screen(screen)) == NULL) return; normalize_rect(&x1, &y1, &x2, &y2); if(!check_range(v, x1, y1, x2, y2)) return; if(mask == 0xff) { for(y = y1; y <= y2; y++) memset(v->data + v->width * y + x1, color, x2 - x1 + 1); } else { int p; for(y = y1; y <= y2; y++) for(x = x1; x <= x2; x++) { int i; i = v->width * y + x; p = v->data[i]; v->data[i] = ROP3_CA0749(mask, color, p); } }}static void vscreen_drawline(VirtualScreen* scr, int x1, int y1, int x2, int y2, int pixel, int mask){ int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag, idx; if(scr == NULL) return; if(x1 < 0 || y1 < 0 || x2 >= scr->width || y2 >= scr->height) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: Out of range: (%d,%d)-(%d,%d)" " > %dx%d, stop sherring", x1, y1, x2, y2, scr->width, scr->height); err_to_stop = 1; return; } dx = x2 - x1; if(dx < 0) dx = -dx; /* dx = |x2-x1| */ dy = y2 - y1; if(dy < 0) dy = -dy; /* dy = |y2-y1| */ if(dy <= dx) { d = 2 * dy - dx; incr1 = 2 * dy; incr2 = 2 * (dy - dx); if(x1 > x2) { x = x2; y = y2; ydirflag = -1; xend = x1; } else { x = x1; y = y1; ydirflag = 1; xend = x2; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); if((y2 - y1) * ydirflag > 0) { while(x < xend) { x++; if(d < 0) d += incr1; else { y++; d += incr2; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); } } else { while(x < xend) { x++; if(d < 0) d += incr1; else { y--; d += incr2; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); } } } else { d = 2 * dx - dy; incr1 = 2 * dx; incr2 = 2 * (dx - dy); if(y1 > y2) { y = y2; x = x2; yend = y1; xdirflag = -1; } else { y = y1; x = x1; yend = y2; xdirflag = 1; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); if((x2 - x1) * xdirflag > 0) { while(y < yend) { y++; if(d <0) d += incr1; else { x++; d += incr2; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); } } else { while(y < yend) { y++; if(d < 0) d += incr1; else { x--; d += incr2; } idx = scr->width * y + x; scr->data[idx] = ROP3_CA0749(mask, pixel, scr->data[idx]); } } }}static void sry_draw_vline(uint8 *data){ int screen = SRY_GET_SHORT(data + 0) & 0xffff; int mask = data[2]; int x1 = SRY_GET_SHORT(data + 3) & 0xffff; int y1 = SRY_GET_SHORT(data + 5) & 0xffff; int y2 = SRY_GET_SHORT(data + 7) & 0xffff; int color = data[9]; vscreen_drawline(virtual_screen(screen), x1, y1, x1, y2, color, mask);}static void sry_draw_hline(uint8 *data){ int screen = SRY_GET_SHORT(data + 0) & 0xffff; int mask = data[2]; int x1 = SRY_GET_SHORT(data + 3) & 0xffff; int x2 = SRY_GET_SHORT(data + 5) & 0xffff; int y1 = SRY_GET_SHORT(data + 7) & 0xffff; int color = data[9]; vscreen_drawline(virtual_screen(screen), x1, y1, x2, y1, color, mask);}static void sry_draw_line(uint8 *data){ int screen = SRY_GET_SHORT(data + 0) & 0xffff; int mask = data[2]; int x1 = SRY_GET_SHORT(data + 3) & 0xffff; int y1 = SRY_GET_SHORT(data + 5) & 0xffff; int x2 = SRY_GET_SHORT(data + 7) & 0xffff; int y2 = SRY_GET_SHORT(data + 9) & 0xffff; int color = data[11]; vscreen_drawline(virtual_screen(screen), x1, y1, x2, y2, color, mask);}static void sry_pal_merge(uint8 *data){ int Pal1, Pal2, PalResult; int Pal1in, Pal1bit, Pal1out; int Pal2in, Pal2bit, Pal2out; int Per1, Per2; int Pal1Mask, Pal2Mask, PalMask; int i; int i1, i2; SherryPaletteEntry *pal_in1, *pal_in2, *pal_res; Pal1 = SRY_GET_SHORT(data + 0) & 0xffff; Pal2 = SRY_GET_SHORT(data + 2) & 0xffff; PalResult = SRY_GET_SHORT(data + 4) & 0xffff; Pal1in = data[6]; Pal1bit = data[7]; Pal1out = data[8]; Pal2in = data[9]; Pal2bit = data[10]; Pal2out = data[11]; Per1 = data[12]; Per2 = data[13]; Pal1Mask = 0xff >> ( 8 - Pal1bit ); Pal1Mask <<= Pal1out; Pal2Mask = 0xff >> ( 8 - Pal2bit ); Pal2Mask <<= Pal2out; PalMask = Pal1Mask | Pal2Mask;#ifdef SRY_DEBUG printf("palette merge %d(%d%%) %d(%d%%) => %d (mask=0x%x)\n", Pal1, Per1, Pal2, Per2, PalResult, PalMask);#endif /* SRY_DEBUG */ if(virtualPalette[Pal1] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: palette %d is not allocated, stop sherring", Pal1); err_to_stop = 1; return; } if(virtualPalette[Pal2] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: palette %d is not allocated, stop sherring", Pal2); err_to_stop = 1; return; } if(virtualPalette[PalResult] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: palette %d is not allocated, stop sherring", PalResult); err_to_stop = 1; return; } pal_in1 = virtualPalette[Pal1]->entry; pal_in2 = virtualPalette[Pal2]->entry; pal_res = virtualPalette[PalResult]->entry; for(i = 0; i < MAX_COLORS; i++) { if((i & PalMask) == i) { int p; i1 = (i & Pal1Mask) >> Pal1in; i2 = (i & Pal2Mask) >> Pal2in; p = pal_in1[i1].r * Per1 / 100 + pal_in2[i2].r * Per2 / 100; if(p > 0xff) p = 0xff; pal_res[i].r = p; p = pal_in1[i1].g * Per1 / 100 + pal_in2[i2].g * Per2 / 100; if(p > 0xff) p = 0xff; pal_res[i].g = p; p = pal_in1[i1].b * Per1 / 100 + pal_in2[i2].b * Per2 / 100; if(p > 0xff) p = 0xff; pal_res[i].b = p; } }}static void sry_pal_copy(uint8 *data){ int pal1, pal2; pal1 = SRY_GET_SHORT(data + 0) & 0xffff; pal2 = SRY_GET_SHORT(data + 2) & 0xffff;#ifdef SRY_DEBUG printf("Copy palette %d->%d\n", pal1, pal2);#endif /* SRY_DEBUG */ if(virtualPalette[pal1] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD: palette %d is not allocated, stop sherring", pal1); err_to_stop = 1; return; } if(virtualPalette[pal2] == NULL) virtualPalette[pal2] = (SherryPalette *)safe_malloc(sizeof(SherryPalette)); memcpy(virtualPalette[pal2], virtualPalette[pal1], sizeof(SherryPalette));}static void sry_text(uint8 *data){ int screen, mask, mode, bg, fg, tx, ty; char *str; int len, advance; VirtualScreen *scr; screen = SRY_GET_SHORT(data + 0); mask = data[2]; mode = data[3]; fg = data[4]; bg = data[5]; tx = SRY_GET_SHORT(data + 6); ty = SRY_GET_SHORT(data + 8); str = (char *)data + 10; len = strlen(str); if(len == 0) return;#ifdef SRY_DEBUG printf("%d 0x%02x %d %d %d (%d,%d)\n%s\n", screen, mask, mode, fg, bg, tx, ty, str);#endif /* SRY_DEBUG */ if((scr = virtual_screen(screen)) == NULL) return; if(!check_range(scr, tx, ty, tx + CHAR_WIDTH1 * len - 1, ty + CHAR_HEIGHT - 1)) return; while((advance = bitmap_drawimage(imageBitmap, str, len)) > 0) { int width, bx, by, p; width = advance * CHAR_WIDTH1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -