⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpng-x.c

📁 game engine, which is useful for everyone who is interested in it. I hope you can enjoy it.
💻 C
📖 第 1 页 / 共 2 页
字号:
        int visuals_matched = 0;

        Trace((stderr, "default depth is %d:  checking other visuals\n",
          depth))

        /* 24-bit first */
        visual_info.screen = screen;
        visual_info.depth = 24;
        visual_list = XGetVisualInfo(display,
          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
        if (visuals_matched == 0) {
/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
            fprintf(stderr, "default screen depth %d not supported, and no"
              " 24-bit visuals found\n", depth);
            return 2;
        }
        Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
          visuals_matched))
        visual = visual_list[0].visual;
        depth = visual_list[0].depth;
/*
        colormap_size = visual_list[0].colormap_size;
        visual_class = visual->class;
        visualID = XVisualIDFromVisual(visual);
 */
        have_nondefault_visual = TRUE;
        need_colormap = TRUE;
    } else {
        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
        visual = visual_info.visual;
    }
#endif

    RMask = visual->red_mask;
    GMask = visual->green_mask;
    BMask = visual->blue_mask;

/* GRR:  add/check 8-bit support */
    if (depth == 8 || need_colormap) {
        colormap = XCreateColormap(display, root, visual, AllocNone);
        if (!colormap) {
            fprintf(stderr, "XCreateColormap() failed\n");
            return 2;
        }
        have_colormap = TRUE;
    }
    if (depth == 15 || depth == 16) {
        RShift = 15 - rpng_x_msb(RMask);    /* these are right-shifts */
        GShift = 15 - rpng_x_msb(GMask);
        BShift = 15 - rpng_x_msb(BMask);
    } else if (depth > 16) {
#define NO_24BIT_MASKS
#ifdef NO_24BIT_MASKS
        RShift = rpng_x_msb(RMask) - 7;     /* these are left-shifts */
        GShift = rpng_x_msb(GMask) - 7;
        BShift = rpng_x_msb(BMask) - 7;
#else
        RShift = 7 - rpng_x_msb(RMask);     /* these are right-shifts, too */
        GShift = 7 - rpng_x_msb(GMask);
        BShift = 7 - rpng_x_msb(BMask);
#endif
    }
    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
        fprintf(stderr, "rpng internal logic error:  negative X shift(s)!\n");
        return 2;
    }

/*---------------------------------------------------------------------------
    Finally, create the window.
  ---------------------------------------------------------------------------*/

    attr.backing_store = Always;
    attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
    attrmask = CWBackingStore | CWEventMask;
    if (have_nondefault_visual) {
        attr.colormap = colormap;
        attr.background_pixel = 0;
        attr.border_pixel = 1;
        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
    }

    window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
      depth, InputOutput, visual, attrmask, &attr);

    if (window == None) {
        fprintf(stderr, "XCreateWindow() failed\n");
        return 2;
    } else
        have_window = TRUE;

    if (depth == 8)
        XSetWindowColormap(display, window, colormap);

    if (!XStringListToTextProperty(&window_name, 1, pWindowName))
        pWindowName = NULL;
    if (!XStringListToTextProperty(&icon_name, 1, pIconName))
        pIconName = NULL;

    /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */

    if ((size_hints = XAllocSizeHints()) != NULL) {
        /* window will not be resizable */
        size_hints->flags = PMinSize | PMaxSize;
        size_hints->min_width = size_hints->max_width = (int)image_width;
        size_hints->min_height = size_hints->max_height = (int)image_height;
    }

    if ((wm_hints = XAllocWMHints()) != NULL) {
        wm_hints->initial_state = NormalState;
        wm_hints->input = True;
     /* wm_hints->icon_pixmap = icon_pixmap; */
        wm_hints->flags = StateHint | InputHint  /* | IconPixmapHint */ ;
    }

    XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
      size_hints, wm_hints, NULL);

    /* various properties and hints no longer needed; free memory */
    if (pWindowName)
       XFree(pWindowName->value);
    if (pIconName)
       XFree(pIconName->value);
    if (size_hints)
        XFree(size_hints);
    if (wm_hints)
       XFree(wm_hints);

    XMapWindow(display, window);

    gc = XCreateGC(display, window, 0, &gcvalues);
    have_gc = TRUE;

/*---------------------------------------------------------------------------
    Fill window with the specified background color.
  ---------------------------------------------------------------------------*/

    if (depth == 24 || depth == 32) {
        bg_pixel = ((ulg)bg_red   << RShift) |
                   ((ulg)bg_green << GShift) |
                   ((ulg)bg_blue  << BShift);
    } else if (depth == 16) {
        bg_pixel = ((((ulg)bg_red   << 8) >> RShift) & RMask) |
                   ((((ulg)bg_green << 8) >> GShift) & GMask) |
                   ((((ulg)bg_blue  << 8) >> BShift) & BMask);
    } else /* depth == 8 */ {

        /* GRR:  add 8-bit support */

    }

    XSetForeground(display, gc, bg_pixel);
    XFillRectangle(display, window, gc, 0, 0, image_width, image_height);

/*---------------------------------------------------------------------------
    Wait for first Expose event to do any drawing, then flush.
  ---------------------------------------------------------------------------*/

    do
        XNextEvent(display, &e);
    while (e.type != Expose || e.xexpose.count);

    XFlush(display);

/*---------------------------------------------------------------------------
    Allocate memory for the X- and display-specific version of the image.
  ---------------------------------------------------------------------------*/

    if (depth == 24 || depth == 32) {
        xdata = (uch *)malloc(4*image_width*image_height);
        pad = 32;
    } else if (depth == 16) {
        xdata = (uch *)malloc(2*image_width*image_height);
        pad = 16;
    } else /* depth == 8 */ {
        xdata = (uch *)malloc(image_width*image_height);
        pad = 8;
    }

    if (!xdata) {
        fprintf(stderr, PROGNAME ":  unable to allocate image memory\n");
        return 4;
    }

    ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
      (char *)xdata, image_width, image_height, pad, 0);

    if (!ximage) {
        fprintf(stderr, PROGNAME ":  XCreateImage() failed\n");
        free(xdata);
        return 3;
    }

    /* to avoid testing the byte order every pixel (or doubling the size of
     * the drawing routine with a giant if-test), we arbitrarily set the byte
     * order to MSBFirst and let Xlib worry about inverting things on little-
     * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
     * efficient approach (the giant if-test would be better), but in the
     * interest of clarity, we take the easy way out... */

    ximage->byte_order = MSBFirst;

    return 0;

} /* end function rpng_x_create_window() */





static int rpng_x_display_image(void)
{
    uch *src;
    char *dest;
    uch r, g, b, a;
    ulg i, row, lastrow = 0;
    ulg pixel;
    int ximage_rowbytes = ximage->bytes_per_line;
/*  int bpp = ximage->bits_per_pixel;  */


    Trace((stderr, "beginning display loop (image_channels == %d)\n",
      image_channels))
    Trace((stderr, "   (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
      image_width, image_rowbytes, ximage_rowbytes))
    Trace((stderr, "   (bpp = %d)\n", ximage->bits_per_pixel))
    Trace((stderr, "   (byte_order = %s)\n", ximage->byte_order == MSBFirst?
      "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))

    if (depth == 24 || depth == 32) {
        ulg red, green, blue;

        for (lastrow = row = 0;  row < image_height;  ++row) {
            src = image_data + row*image_rowbytes;
            dest = ximage->data + row*ximage_rowbytes;
            if (image_channels == 3) {
                for (i = image_width;  i > 0;  --i) {
                    red   = *src++;
                    green = *src++;
                    blue  = *src++;
#ifdef NO_24BIT_MASKS
                    pixel = (red   << RShift) |
                            (green << GShift) |
                            (blue  << BShift);
                    /* recall that we set ximage->byte_order = MSBFirst above */
                    /* GRR BUG:  this assumes bpp == 32, but may be 24: */
                    *dest++ = (char)((pixel >> 24) & 0xff);
                    *dest++ = (char)((pixel >> 16) & 0xff);
                    *dest++ = (char)((pixel >>  8) & 0xff);
                    *dest++ = (char)( pixel        & 0xff);
#else
                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;
                    green = (GShift < 0)? green << (-GShift) : green >> GShift;
                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;
                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);
                    /* recall that we set ximage->byte_order = MSBFirst above */
                    *dest++ = (char)((pixel >> 24) & 0xff);
                    *dest++ = (char)((pixel >> 16) & 0xff);
                    *dest++ = (char)((pixel >>  8) & 0xff);
                    *dest++ = (char)( pixel        & 0xff);
#endif
                }
            } else /* if (image_channels == 4) */ {
                for (i = image_width;  i > 0;  --i) {
                    r = *src++;
                    g = *src++;
                    b = *src++;
                    a = *src++;
                    if (a == 255) {
                        red   = r;
                        green = g;
                        blue  = b;
                    } else if (a == 0) {
                        red   = bg_red;
                        green = bg_green;
                        blue  = bg_blue;
                    } else {
                        /* this macro (from png.h) composites the foreground
                         * and background values and puts the result into the
                         * first argument */
                        alpha_composite(red,   r, a, bg_red);
                        alpha_composite(green, g, a, bg_green);
                        alpha_composite(blue,  b, a, bg_blue);
                    }
                    pixel = (red   << RShift) |
                            (green << GShift) |
                            (blue  << BShift);
                    /* recall that we set ximage->byte_order = MSBFirst above */
                    *dest++ = (char)((pixel >> 24) & 0xff);
                    *dest++ = (char)((pixel >> 16) & 0xff);
                    *dest++ = (char)((pixel >>  8) & 0xff);
                    *dest++ = (char)( pixel        & 0xff);
                }
            }
            /* display after every 16 lines */
            if (((row+1) & 0xf) == 0) {
                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
                  (int)lastrow, image_width, 16);
                XFlush(display);
                lastrow = row + 1;
            }
        }

    } else if (depth == 16) {
        ush red, green, blue;

        for (lastrow = row = 0;  row < image_height;  ++row) {
            src = image_data + row*image_rowbytes;
            dest = ximage->data + row*ximage_rowbytes;
            if (image_channels == 3) {
                for (i = image_width;  i > 0;  --i) {
                    red   = ((ush)(*src) << 8);
                    ++src;
                    green = ((ush)(*src) << 8);
                    ++src;
                    blue  = ((ush)(*src) << 8);
                    ++src;
                    pixel = ((red   >> RShift) & RMask) |
                            ((green >> GShift) & GMask) |
                            ((blue  >> BShift) & BMask);
                    /* recall that we set ximage->byte_order = MSBFirst above */
                    *dest++ = (char)((pixel >>  8) & 0xff);
                    *dest++ = (char)( pixel        & 0xff);
                }
            } else /* if (image_channels == 4) */ {
                for (i = image_width;  i > 0;  --i) {
                    r = *src++;
                    g = *src++;
                    b = *src++;
                    a = *src++;
                    if (a == 255) {
                        red   = ((ush)r << 8);
                        green = ((ush)g << 8);
                        blue  = ((ush)b << 8);
                    } else if (a == 0) {
                        red   = ((ush)bg_red   << 8);
                        green = ((ush)bg_green << 8);
                        blue  = ((ush)bg_blue  << 8);
                    } else {
                        /* this macro (from png.h) composites the foreground
                         * and background values and puts the result back into
                         * the first argument (== fg byte here:  safe) */
                        alpha_composite(r, r, a, bg_red);
                        alpha_composite(g, g, a, bg_green);
                        alpha_composite(b, b, a, bg_blue);
                        red   = ((ush)r << 8);
                        green = ((ush)g << 8);
                        blue  = ((ush)b << 8);
                    }
                    pixel = ((red   >> RShift) & RMask) |
                            ((green >> GShift) & GMask) |
                            ((blue  >> BShift) & BMask);
                    /* recall that we set ximage->byte_order = MSBFirst above */
                    *dest++ = (char)((pixel >>  8) & 0xff);
                    *dest++ = (char)( pixel        & 0xff);
                }
            }
            /* display after every 16 lines */
            if (((row+1) & 0xf) == 0) {
                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
                  (int)lastrow, image_width, 16);
                XFlush(display);
                lastrow = row + 1;
            }
        }

    } else /* depth == 8 */ {

        /* GRR:  add 8-bit support */

    }

    Trace((stderr, "calling final XPutImage()\n"))
    if (lastrow < image_height) {
        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
          (int)lastrow, image_width, image_height-lastrow);
        XFlush(display);
    }

    return 0;
}




static void rpng_x_cleanup(void)
{
    if (image_data) {
        free(image_data);
        image_data = NULL;
    }

    if (ximage) {
        if (ximage->data) {
            free(ximage->data);           /* we allocated it, so we free it */
            ximage->data = (char *)NULL;  /*  instead of XDestroyImage() */
        }
        XDestroyImage(ximage);
        ximage = NULL;
    }

    if (have_gc)
        XFreeGC(display, gc);

    if (have_window)
        XDestroyWindow(display, window);

    if (have_colormap)
        XFreeColormap(display, colormap);

    if (have_nondefault_visual)
        XFree(visual_list);
}





static int rpng_x_msb(ulg u32val)
{
    int i;

    for (i = 31;  i >= 0;  --i) {
        if (u32val & 0x80000000L)
            break;
        u32val <<= 1;
    }
    return i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -