📄 x_sherry.c
字号:
if(virtualPalette[n] != NULL) { free(virtualPalette[n]); virtualPalette[n] = NULL; } }}static void sry_new_vram(uint8 *data, int len){ int i, n, width, height, c; for(i = 0; i < len-6; i += 7) { n = SRY_GET_SHORT(data + i) & 0xffff; width = SRY_GET_SHORT(data + i + 2) & 0xffff; height = SRY_GET_SHORT(data + i + 4) & 0xffff; c = data[6];#ifdef SRY_DEBUG printf("sherry: new vram[%d] %dx%d (t=%d)\n", n, width, height, c);#endif /* SRY_DEBUG */ if(virtualScreen[n] != NULL) free_vscreen(virtualScreen[n]); virtualScreen[n] = alloc_vscreen(width, height, c); }}static void sry_free_vram(uint8 *data, int len){ int i, n; for(i = 0; i < len-1; i += 2) { n = SRY_GET_SHORT(data + i) & 0xffff; if(virtualScreen[n] != NULL) { free_vscreen(virtualScreen[n]); virtualScreen[n] = NULL; } }}static void sry_pal_set(uint8 *data, int len){ int pg, i, p; SherryPaletteEntry *entry; pg = SRY_GET_SHORT(data) & 0xffff; if(virtualPalette[pg] == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "WRD Sherry: virtual palette %d is not allocated", pg); err_to_stop = 1; return; } entry = virtualPalette[pg]->entry; data += 2; len -= 2;#ifdef SRY_DEBUG printf("set palette color of %d (n=%d)\n", pg, len / 4);#endif /* SRY_DEBUG */ for(i = 0; i < len - 3; i += 4) { p = data[i]; entry[p].r = data[i + 1]; entry[p].g = data[i + 2]; entry[p].b = data[i + 3]; }}static void update_real_screen(int x, int y, int width, int height){ if(!draw_ctl_flag) return;#if XSHM_SUPPORT if(theRealScreen->shminfo.shmid != -1) { XShmPutImage(theDisplay, theWindow, theGC, theRealScreen->im, x, y, x, y, width, height, False); return; }#endif XPutImage(theDisplay, theWindow, theGC, theRealScreen->im, x, y, x, y, width, height);}static void updateScreen(int sx, int sy, int width, int height){ if(theClass == TrueColor) { XImage *im; int x, y, c; int units_per_line; unsigned long pixels[MAX_COLORS]; for(c = 0; c < MAX_COLORS; c++) pixels[c] = trueColorPixel(realPalette[c].r, realPalette[c].g, realPalette[c].b); im = theRealScreen->im; units_per_line = im->bytes_per_line / (im->bits_per_pixel / 8); switch(im->bits_per_pixel) {#if 1 case 8: for(y = 0; y < height; y++) for(x = 0; x < width; x++) { c = pseudoImage[(sy + y) * REAL_SCREEN_SIZE_X + sx + x]; im->data[(sy + y) * units_per_line + sx + x] = pixels[c]; } break; case 16: for(y = 0; y < height; y++) for(x = 0; x < width; x++) { c = pseudoImage[(sy + y) * REAL_SCREEN_SIZE_X + sx + x]; ((uint16 *)im->data)[(sy + y) * units_per_line + sx + x] = pixels[c]; } break; case 32: for(y = 0; y < height; y++) for(x = 0; x < width; x++) { c = pseudoImage[(sy + y) * REAL_SCREEN_SIZE_X + sx + x]; ((uint32 *)im->data)[(sy + y) * units_per_line + sx + x] = pixels[c]; } break;#endif default: /* Generic routine */ for(y = 0; y < height; y++) for(x = 0; x < width; x++) { c = pseudoImage[(sy + y) * REAL_SCREEN_SIZE_X + sx + x]; XPutPixel(theRealScreen->im, sx + x, sy + y, pixels[c]); } break; } } update_real_screen(sx, sy, width, height); isRealScreenChanged = 0;}static void updatePalette(void){ int i; XColor xc[256]; if(theClass != TrueColor) { for(i = 0; i < MAX_COLORS; i++) { xc[i].pixel = palette2Pixel[i]; xc[i].red = realPalette[i].r * 257; xc[i].green = realPalette[i].g * 257; xc[i].blue = realPalette[i].b * 257; xc[i].flags = DoRed | DoGreen | DoBlue; } XStoreColors(theDisplay, theColormap, xc, MAX_COLORS); } else /* True color */ { updateScreen(0, 0, REAL_SCREEN_SIZE_X, REAL_SCREEN_SIZE_Y); isRealScreenChanged = 0; } isRealPaletteChanged = 0;}static void sry_pal_v2r(uint8 *data){ int n; n = SRY_GET_SHORT(data) & 0xffff;#ifdef SRY_DEBUG printf("Transfer palette %d\n", n);#endif /* SRY_DEBUG */ if(virtualPalette[n] == NULL) { virtualPalette[n] = (SherryPalette *)safe_malloc(sizeof(SherryPalette)); memset(virtualPalette[n], 0, sizeof(SherryPalette)); } memcpy(realPalette, virtualPalette[n]->entry, sizeof(realPalette)); isRealPaletteChanged = 1; currentPalette = n;}static void png_read_func(png_structp png_ptr, char *buff, size_t n){ struct timidity_file *tf; tf = (struct timidity_file *)png_ptr->io_ptr; tf_read(buff, 1, n, tf);}#define PNG_BYTES_TO_CHECK 8#define MAX_SCREEN_COLORS 256static void sry_load_png(uint8 *data){ int i; int x, y; int screen, vpalette; png_structp pngPtr; png_infop infoPtr; png_infop endInfo; VirtualScreen *scr; SherryPaletteEntry *entry; char *filename; struct timidity_file *tf; char sig[PNG_BYTES_TO_CHECK]; png_uint_32 width, height; int bitDepth, colorType, interlaceType, compressionType, filterType; int numPalette; png_colorp palette; png_uint_16p hist; png_bytep *rowPointers; png_uint_32 rowbytes; png_bytep trans; int transParent; int numTrans; png_color_16p transValues; numPalette = -1; memset(&palette, 0, sizeof(palette)); hist = NULL; rowbytes = 0; rowPointers = NULL; trans = NULL; numTrans = 0; transValues = NULL; screen = SRY_GET_SHORT(data) & 0xffff; vpalette = SRY_GET_SHORT(data + 2) & 0xffff; filename = data + 4;#ifdef SRY_DEBUG printf("Load png: %s: scr=%d pal=%d\n", filename, screen, vpalette);#endif /* SRY_DEBUG */ if((tf = wrd_open_file(filename)) == NULL) { err_to_stop = 1; return; } if(tf_read(sig, 1, sizeof(sig), tf) != sizeof(sig)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "WRD Sherry: %s is too short to be png format.", filename); err_to_stop = 1; return; } if(png_sig_cmp(sig, 0, sizeof(sig))) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: Not a png file", filename); err_to_stop = 1; return; } pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); infoPtr = png_create_info_struct(pngPtr); endInfo = png_create_info_struct(pngPtr); png_set_read_fn(pngPtr, (void *)tf, (png_rw_ptr)png_read_func); png_set_sig_bytes(pngPtr, sizeof(sig)); png_read_info(pngPtr, infoPtr); /* get info */ png_get_IHDR(pngPtr, infoPtr, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterType); /* transformation */ /* contert to 256 palette */ if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) png_set_expand(pngPtr); if(bitDepth == 16) png_set_strip_16(pngPtr); if(bitDepth < 8) png_set_packing(pngPtr); if(colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(pngPtr);#if 0 double screenGamma; const char* const gammaStr = getenv ("SCREEN_GAMMA"); if (gammaStr != NULL) { screenGamma = atof (gammaStr); } else { screenGamma = 2.2;/* screenGamms = 2.0; screenGamms = 1.7; screenGamms = 1.0;*/ } if (png_get_gAMA (pngPtr, infoPtr, &gamma)) png_set_gamma (pngPtr, screenGamma, gamma); else png_set_gamma (pngPtr, screenGamma, 0.50);#endif if(png_get_valid(pngPtr, infoPtr, PNG_INFO_PLTE)) { png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette); if(numPalette > MAX_SCREEN_COLORS) { if(png_get_valid(pngPtr, infoPtr, PNG_INFO_hIST)) png_get_hIST(pngPtr, infoPtr, &hist); png_set_dither(pngPtr, palette, numPalette, MAX_SCREEN_COLORS, hist, 1); } } else { /* XXX */ /* NOTE 6*7*6 = 252 */ /* 6*7*6 = 5*7*6 + 6*6 + 6 */ png_color stdColorCube[6*7*6]; png_byte r, g, b; for(r = 0; r < 6; r++) { for(g = 0; g < 7; g++) { for(b = 0; b < 6; b++) { png_byte index = r*7*6+g*6+b; stdColorCube[index].red = r; stdColorCube[index].green = g; stdColorCube[index].blue = b; } } } png_set_dither(pngPtr, stdColorCube, 6*7*6, MAX_SCREEN_COLORS, NULL, 1); /*???*/ png_set_PLTE(pngPtr, infoPtr, pngPtr->palette, pngPtr->num_palette); palette = pngPtr->palette; numPalette = pngPtr->num_palette; } if(png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) png_get_tRNS(pngPtr, infoPtr, &trans, &numTrans, &transValues); png_read_update_info(pngPtr, infoPtr); rowbytes = png_get_rowbytes(pngPtr, infoPtr); /* rowbytes == width */ rowPointers = (png_bytep *)safe_malloc(height * sizeof(png_bytep)); rowPointers[0] = (png_byte *)safe_malloc(rowbytes * height * sizeof(png_byte)); for(i = 1; i < height; i++) rowPointers[i] = rowPointers[0] + i * rowbytes; png_read_image(pngPtr, rowPointers); png_read_end(pngPtr, endInfo); if(trans == NULL || numTrans == 0) transParent = 0; else transParent = trans[0] & 0xff; scr = virtualScreen[screen]; if(scr != NULL && (scr->width != width || scr->height != height)) { free_vscreen(scr); scr = NULL; } if(scr == NULL) scr = virtualScreen[screen] = alloc_vscreen(width, height*2, transParent); else scr->transParent = transParent; if(virtualPalette[vpalette] == NULL) { virtualPalette[vpalette] = (SherryPalette *)safe_malloc(sizeof(SherryPalette)); memset(virtualPalette[vpalette], 0, sizeof(SherryPalette)); } entry = virtualPalette[vpalette]->entry; for(i = 0; i < numPalette; i++) { entry[i].r = palette[i].red; entry[i].g = palette[i].green; entry[i].b = palette[i].blue; } for(y = 0; y < height; y++) for(x = 0; x < width; x++) VSCREEN_PIXEL(scr, x, y) = rowPointers[y][x]; free(rowPointers[0]); free(rowPointers); png_destroy_read_struct(&pngPtr, &infoPtr, &endInfo); close_file(tf);#ifdef SRY_DEBUG printf("Load png ok: width=%d height=%d\n", width, height);#endif /* SRY_DEBUG */}static void sry_trans_all(uint8 *data){ int screen, x, y; int sx, sy; VirtualScreen *scr; XImage *im; screen = SRY_GET_SHORT(data + 0) & 0xffff; sx = SRY_GET_SHORT(data + 2) & 0xffff; sy = SRY_GET_SHORT(data + 4) & 0xffff; im = theRealScreen->im; scr = virtualScreen[screen];#ifdef SRY_DEBUG printf("Trans all: %d:(%d,%d)\n", screen, sx, sy);#endif /* SRY_DEBUG */ if(!check_range(scr, sx, sy, sx + REAL_SCREEN_SIZE_X - 1, sy + REAL_SCREEN_SIZE_Y - 1)) return; if(theClass != TrueColor) { for(y = 0; y < REAL_SCREEN_SIZE_Y; y++) for(x = 0; x < REAL_SCREEN_SIZE_X; x++) XPutPixel(im, x, y, VSCREEN_PIXEL(scr, sx + x, sy + y)); } else /* TrueColor */ { for(y = 0; y < REAL_SCREEN_SIZE_Y; y++) memcpy(pseudoImage + y * REAL_SCREEN_SIZE_X, scr->data + (sy + y) * scr->width + sx, REAL_SCREEN_SIZE_X); } isRealScreenChanged = 1; updateClipX1 = 0; updateClipY1 = 0; updateClipX2 = REAL_SCREEN_SIZE_X-1; updateClipY2 = REAL_SCREEN_SIZE_Y-1;}static void sry_trans_partial_real(uint8 *data){ int screen, sx, sy, tx, ty, w, h, x, y; int x2, y2; VirtualScreen *scr; XImage *im; screen = SRY_GET_SHORT(data + 0) & 0xffff; sx = SRY_GET_SHORT(data + 2) & 0xffff; sy = SRY_GET_SHORT(data + 4) & 0xffff; tx = SRY_GET_SHORT(data + 6) & 0xffff; ty = SRY_GET_SHORT(data + 8) & 0xffff; w = SRY_GET_SHORT(data +10) & 0xffff; h = SRY_GET_SHORT(data +12) & 0xffff; x2 = tx + w - 1; if(x2 >= REAL_SCREEN_SIZE_X) { x2 = REAL_SCREEN_SIZE_X - 1; w = x2 - tx + 1; } y2 = ty + h - 1; if(y2 >= REAL_SCREEN_SIZE_Y) { y2 = REAL_SCREEN_SIZE_Y - 1; h = y2 - ty + 1; }#ifdef SRY_DEBUG printf("Trans partial: %d:(%d,%d) (%d,%d) %dx%d\n", screen, sx, sy, tx, ty, w, h);#endif /* SRY_DEBUG */ im = theRealScreen->im; scr = virtualScreen[screen]; if(theClass != TrueColor) { for(y = 0; y < h; y++) for(x = 0; x < w; x++) XPutPixel(im, tx + x, ty + y, VSCREEN_PIXEL(scr, sx + x, sy + y)); } else { for(y = 0; y < h; y++) { memcpy(pseudoImage + (ty + y) * REAL_SCREEN_SIZE_X + tx, scr->data + (sy + y) * scr->width + sx, w); } } if(isRealScreenChanged) { /*???*/ x_sry_update(); } updateClipX1 = tx; updateClipY1 = ty; updateClipX2 = x2; updateClipY2 = y2; isRealScreenChanged = 1;}static VirtualScreen *get_tmp_screen(int width_require, int height_require){ if(tmpScreen == NULL) { if(width_require < REAL_SCREEN_SIZE_X) width_require = REAL_SCREEN_SIZE_X; if(height_require < REAL_SCREEN_SIZE_Y) height_require = REAL_SCREEN_SIZE_Y; return tmpScreen = alloc_vscreen(width_require, height_require, 0); } if(tmpScreen->width * tmpScreen->height >= width_require * height_require) { tmpScreen->width = width_require; tmpScreen->height = height_require; return tmpScreen; } if(tmpScreen) free_vscreen(tmpScreen); return tmpScreen = alloc_vscreen(width_require, height_require, 0);}static void normalize_rect(int *x1, int *y1, int *x2, int *y2){ int w, h, x0, y0; w = *x2 - *x1; if(w >= 0) x0 = *x1; else { w = -w; x0 = *x2; } h = *y2 - *y1; if(h >= 0) y0 = *y1; else { h = -h; y0 = *y2; } *x1 = x0; *y1 = y0; *x2 = x0 + w; *y2 = y0 + h;}static int check_range(VirtualScreen *scr, int x1, int y1, int x2, int y2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -