📄 x_sherry.c
字号:
for(by = 0; by < CHAR_HEIGHT; by++) { for(bx = 0; bx < width; bx++) { if(XGetPixel(imageBitmap->im, bx, by)) { if(mode & 1) { p = VSCREEN_PIXEL(scr, tx + bx, ty + by); VSCREEN_PIXEL(scr, tx + bx, ty + by) = ROP3_CA0749(mask, fg, p); } } else { if(mode & 2) { p = VSCREEN_PIXEL(scr, tx + bx, ty + by); VSCREEN_PIXEL(scr, tx + bx, ty + by) = ROP3_CA0749(mask, bg, p); } } } } str += advance; len -= advance; tx += advance * CHAR_WIDTH1; }}void x_sry_clear(void){ int i; if(theDisplay == NULL) return; isRealPaletteChanged = 0; isRealScreenChanged = 0; err_to_stop = 0; init_palette(); XSetWindowBackground(theDisplay, theWindow, basePixel); XClearWindow(theDisplay, theWindow); clear_image_pixmap(theRealScreen, basePixel); for(i = 0; i < MAX_VIRTUAL_SCREENS; i++) if(virtualScreen[i] != NULL) { free_vscreen(virtualScreen[i]); virtualScreen[i] = NULL; } if(tmpScreen) { free(tmpScreen); tmpScreen = NULL; } for(i = 0; i < MAX_VIRTUAL_PALETTES; i++) if(virtualPalette[i] != NULL) { free(virtualPalette[i]); virtualPalette[i] = NULL; } memset(realPalette, 0, sizeof(realPalette)); if(theClass == TrueColor) memset(pseudoImage, 0, REAL_SCREEN_SIZE_X * REAL_SCREEN_SIZE_Y);}#ifdef SRY_DEBUGstatic void print_command(uint8 *data, int len){ int i; printf("sherry:"); for(i = 0; i < len; i++) { printf(" 0x%02x", data[i]); if(i >= 28) { printf("..."); break; } } printf("\n"); fflush(stdout);}#endif /* SRY_DEBUG */void x_sry_wrdt_apply(uint8 *data, int len){ int op, skip_bit; if(err_to_stop || theDisplay == NULL) return;#ifdef SRY_DEBUG print_command(data, len);#endif /* SRY_DEBUG */ op = *data++; len--; skip_bit = op & 0x80; if(skip_bit && aq_filled_ratio() < 0.2) return; op &= 0x7F; switch(op) { case 0x00: /* DataEnd */ break; case 0x01: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "sherry start"); wrd_init_path(); x_sry_clear(); break; case 0x21: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "new pal 0x21"); sry_new_vpal(data, len); break; case 0x22: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "free pal 0x22"); sry_free_vpal(data, len); break; case 0x25: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "new vram 0x25"); sry_new_vram(data, len); break; case 0x26: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "free vram 0x26"); sry_free_vram(data, len); break; case 0x27: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "load PNG 0x27"); sry_load_png(data); break; case 0x31: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "palette trans 0x31 (%d)", SRY_GET_SHORT(data)); sry_pal_v2r(data); break; case 0x35: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "image copy 0x35 (%d)", SRY_GET_SHORT(data)); sry_trans_all(data); break; case 0x36: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "image copy 0x36 (%d)", SRY_GET_SHORT(data)); sry_trans_partial_real(data); break; case 0x41: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "set pal 0x41"); sry_pal_set(data, len); break; case 0x42: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "pal merge 0x42"); sry_pal_merge(data); break; case 0x43: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "pal copy 0x43"); sry_pal_copy(data); break; case 0x51: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "text 0x51"); sry_text(data); break; case 0x52: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "draw box 0x52"); sry_draw_box(data); break; case 0x53: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "draw line 0x53"); sry_draw_vline(data); break; case 0x54: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "draw line 0x54"); sry_draw_hline(data); break; case 0x55: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "draw line 0x55"); sry_draw_line(data); break; case 0x61: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "image copy 0x61"); sry_trans_partial(data); break; case 0x62: ctl->cmsg(CMSG_INFO, VERB_DEBUG, "image copy 0x62"); sry_trans_partial_mask(data); break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x20: case 0x71: case 0x72: case 0x7f: ctl->cmsg(CMSG_WARNING, VERB_DEBUG, "Sherry WRD 0x%x: not supported, ignore", op); break; default: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Sherry WRD 0x%x: not defined, stop sherring", op); err_to_stop = 1; break; }}void x_sry_redraw_ctl(int flag){ draw_ctl_flag = flag; if(draw_ctl_flag) update_real_screen(0, 0, REAL_SCREEN_SIZE_X, REAL_SCREEN_SIZE_Y);}void x_sry_update(void){ if(err_to_stop) return;#ifdef SRY_DEBUG puts("Update pallete & screen");#endif /* SRY_DEBUG */ if(!isRealPaletteChanged && !isRealScreenChanged) return; if(isRealPaletteChanged) updatePalette(); if(isRealScreenChanged) updateScreen(updateClipX1, updateClipY1, updateClipX2 - updateClipX1 + 1, updateClipY2 - updateClipY1 + 1); XSync(theDisplay, False);}/**** ImagePixmap interfaces ****/static ImagePixmap *create_image_pixmap(int width, int height, int depth){ ImagePixmap *ip; ip = (ImagePixmap *)safe_malloc(sizeof(ImagePixmap)); ip->pm = XCreatePixmap(theDisplay, theWindow, width, height, depth); ip->im = XGetImage(theDisplay, ip->pm, 0, 0, width, height, AllPlanes, ZPixmap); ip->gc = createGC(theDisplay, ip->pm); ip->depth = depth;#if XSHM_SUPPORT ip->shminfo.shmid = -1;#endif return ip;}#if XSHM_SUPPORTstatic int shm_error;static int my_err_handler(Display* dpy, XErrorEvent* e){ shm_error = e->error_code; ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Warning: X Sherry Warning: Can't create SHM Pixmap. error-code=%d", shm_error); return shm_error;}static ImagePixmap *create_shm_image_pixmap(int width, int height, int depth){ XErrorHandler origh; ImagePixmap *ip; int shm_depth; shm_depth = depth; ip = (ImagePixmap *)safe_malloc(sizeof(ImagePixmap)); shm_error = 0; origh = XSetErrorHandler(my_err_handler); /* There is no need to initialize XShmSegmentInfo structure * before the call to XShmCreateImage. */ ip->im = XShmCreateImage(theDisplay, theVisual, shm_depth, ZPixmap, NULL, &ip->shminfo, width, height); if(ip->im == NULL) { if(shm_error == 0) shm_error = -1; goto done; } /* The next step is to create the shared memory segment. * The return value of shmat() should be stored both * the XImage structure and the shminfo structure. */ ip->shminfo.shmid = shmget(IPC_PRIVATE, ip->im->bytes_per_line * ip->im->height, IPC_CREAT | 0777); if(ip->shminfo.shmid == -1) { ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X Sherry Warning: Can't create SHM Pixmap.\n" "shmget: %s", strerror(errno)); XDestroyImage(ip->im); ip->im = NULL; shm_error = -1; goto done; } ip->shminfo.shmaddr = ip->im->data = (char *)shmat(ip->shminfo.shmid, NULL, 0); if(ip->shminfo.shmaddr == (void *)-1) { ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X Sherry Warning: Can't create SHM Pixmap.\n" "shmget: %s", strerror(errno)); shmctl(ip->shminfo.shmid, IPC_RMID, NULL); XDestroyImage(ip->im); ip->im = NULL; shm_error = -1; goto done; } /* If readOnly is True, XShmGetImage calls will fail. */ ip->shminfo.readOnly = False; /* Tell the server to attach to your shared memory segment. */ if(XShmAttach(theDisplay, &ip->shminfo) == 0) { if(shm_error == 0) { ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X Sherry Warning: Can't create SHM Pixmap.\n" "Can't attach to the shared memory segment."); shm_error = -1; } shmdt(ip->shminfo.shmaddr); shmctl(ip->shminfo.shmid, IPC_RMID, NULL); XDestroyImage(ip->im); ip->im = NULL; goto done; } XSync(theDisplay, False); /* Wait until ready. */ ip->pm = XShmCreatePixmap(theDisplay, theWindow, ip->im->data, &ip->shminfo, width, height, shm_depth); if(ip->pm == None) { if(shm_error == 0) { ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "X Sherry Warning: Can't create SHM Pixmap.\n" "XShmCreatePixmap() is failed"); shm_error = -1; } shmdt(ip->shminfo.shmaddr); shmctl(ip->shminfo.shmid, IPC_RMID, NULL); XDestroyImage(ip->im); ip->im = NULL; goto done; } done: XSetErrorHandler(origh); if(ip->im != NULL) { ip->gc = createGC(theDisplay, ip->pm); ip->depth = shm_depth; } else { free(ip); ip = create_image_pixmap(width, height, depth); } return ip;}#endifstatic void clear_image_pixmap(ImagePixmap *ip, unsigned long pixel){ int x, y, w, h; w = ip->im->width; h = ip->im->height; XSetForeground(theDisplay, ip->gc, pixel); XFillRectangle(theDisplay, ip->pm, ip->gc, 0, 0, ip->im->width, ip->im->height);#if XSHM_SUPPORT if(ip->shminfo.shmid != -1) return;#endif /* XSHM_SUPPORT */ for(y = 0; y < h; y++) for(x = 0; x < w; x++){ XPutPixel(ip->im, x, y, pixel); }}static void free_image_pixmap(ImagePixmap *ip){ XFreePixmap(theDisplay, ip->pm);#if XSHM_SUPPORT if(ip->shminfo.shmid != -1) { /* To destory a shard memory XImage, you should call XShmDetach() * first. */ XShmDetach(theDisplay, &ip->shminfo); /* Unmap shared memory segment */ shmdt(ip->shminfo.shmaddr); /* Remove a shared memory ID from the system */ shmctl(ip->shminfo.shmid, IPC_RMID, NULL); }#endif /* XSHM_SUPPORT */ XDestroyImage(ip->im); free(ip);}#define IS_MULTI_BYTE(c) (((c)&0x80) && \ ((0x1 <= ((c)&0x7F) && ((c)&0x7F) <= 0x1f) || \ (0x60 <= ((c)&0x7F) && ((c)&0x7F) <= 0x7c)))/* bitmap_drawimage() Draws string into image * It returns number of bytes drawn */static int bitmap_drawimage(ImagePixmap *ip, char *sjis_str, int nbytes){ int write_len; int sjis_c1, sjis_c2; int x, width, height; x = write_len = 0; while(*sjis_str && write_len < IMAGEBITMAPLEN) { sjis_c1 = *sjis_str & 0xff; sjis_str++; if(IS_MULTI_BYTE(sjis_c1)) { int e1, e2; XChar2b b; if(write_len+1 == IMAGEBITMAPLEN) break; sjis_c2 = *sjis_str & 0xff; if(sjis_c2 == 0) break; sjis_str++; /* SJIS to EUC */ if(sjis_c2 >= 0x9f) { if(sjis_c1 >= 0xe0) e1 = sjis_c1 * 2 - 0xe0; else e1 = sjis_c1 * 2 - 0x60; e2 = sjis_c2 + 2; } else { if(sjis_c1 >= 0xe0) e1 = sjis_c1 * 2 - 0xe1; else e1 = sjis_c1 * 2 - 0x61; if(sjis_c2 >= 0x7f) e2 = sjis_c2 + 0x60; else e2 = sjis_c2 + 0x61; } b.byte1 = e1 & 0x7f; b.byte2 = e2 & 0x7f; XSetFont(theDisplay, ip->gc, theFont16->fid); XDrawImageString16(theDisplay, ip->pm, ip->gc, x - lbearing16, ascent16, &b, 1); x += CHAR_WIDTH2; write_len += 2; } else { char c = sjis_c1; XSetFont(theDisplay, ip->gc, theFont8->fid); XDrawImageString(theDisplay, ip->pm, ip->gc, x - lbearing8, ascent8, &c, 1); x += CHAR_WIDTH1; write_len++; } } if(write_len == 0) return 0; /* Terminate repeating call */#if XSHM_SUPPORT if(ip->shminfo.shmid != -1) { XSync(theDisplay, 0); /* Wait until ready */ return write_len; }#endif /* XSHM_SUPPORT */ /* XSHM is not supported. * Now, re-allocate XImage structure from the pixmap. */ width = ip->im->width; height = ip->im->height; XDestroyImage(ip->im); ip->im = XGetImage(theDisplay, ip->pm, 0, 0, width, height, AllPlanes, ZPixmap); return write_len;}/**** VirtualScreen intarfaces ****/static VirtualScreen *alloc_vscreen(int width, int height, int transParent){ VirtualScreen *scr; int size = width * height; /* Shared the allocated memory for data and the structure */ scr = (VirtualScreen *)safe_malloc(sizeof(VirtualScreen) + size); scr->width = width; scr->height = height; scr->transParent = transParent; memset(scr->data, transParent, size); return scr;}static void free_vscreen(VirtualScreen *scr){ free(scr);}void x_sry_event(void){ if(QLength(theDisplay) == 0) XSync(theDisplay, False); while(QLength(theDisplay) > 0) { XEvent e; XNextEvent(theDisplay, &e); switch(e.type) { case Expose: update_real_screen(e.xexpose.x, e.xexpose.y, e.xexpose.width, e.xexpose.height); break; } if(QLength(theDisplay) == 0) XSync(theDisplay, False); }}#endif /* ENABLE_SHERRY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -