AW: AW: Implementing PseudoColor support on TrueColor screens

Sleep ireallyhatespam at yandex.com
Tue Jun 2 18:30:12 UTC 2020


This should be slightly easier to read:

Display*	X_display = NULL;
Window		X_mainWindow;
Colormap	X_cmap;
Visual*		X_visual;
GC		X_gc;
int		X_screen;
XVisualInfo	X_visualinfo;
XImage*		image = NULL;
int		X_width;
int		X_height;

unsigned long st2d_8to24table[256];
int32_t  shiftmask_fl = 0;
int32_t  r_shift, g_shift, b_shift;
uint32_t r_mask, g_mask, b_mask;

//
// I_InitGraphics
//
// Creates and maps window
void I_InitGraphics (void)
{
     char* displayname = NULL;

     X_width = SCREENWIDTH;
     X_height = SCREENHEIGHT;

     // open the display
     X_display = XOpenDisplay(displayname);

     // use the default visual
     X_screen = DefaultScreen(X_display);
     XMatchVisualInfo(X_display, X_screen, 24, TrueColor, &X_visualinfo);
     X_visual = X_visualinfo.visual;

     // create the main window
     X_mainWindow = XCreateWindow(X_display,
                                  RootWindow(X_display, X_screen),
                                  0, 0,
                                  X_width, X_height,
                                  0, // borderwidth
                                  X_visualinfo.depth, // depth
                                  InputOutput,
                                  X_visual,
                                  0,
                                  0);

     // create the GC
     X_gc = XCreateGC(X_display,
                      X_mainWindow,
                      0,
                      NULL);

     // map the window
     XMapWindow(X_display, X_mainWindow);

     image = XCreateImage(X_display,
                          X_visual,
                          X_visualinfo.depth,
                          ZPixmap,
                          0,
                          malloc((X_width * 4) * X_height),
                          X_width, X_height,
                          32,
                          0);

     screens[0] = (byte *)image->data;
}

// Convert colors to 24 bits, called by I_FinishUpdate()
void st3_fixup (int width, int height)
{
     uint8_t *row_src;

     for (int y = 0; y < height; y++) {
         row_src = (uint8_t *)&image->data [y * image->bytes_per_line];
	for (int x = width-1; x >= 0; x--) {
             XPutPixel(image, x, y, st2d_8to24table[row_src[x]]);
	}
     }
}

// Called by xlib_rgb24()
void shiftmask_init (void)
{
     unsigned int x;

     r_mask = X_visual->red_mask;
     g_mask = X_visual->green_mask;
     b_mask = X_visual->blue_mask;

     for (r_shift = -8, x = 1; x < r_mask; x = x << 1)
         r_shift++;

     for (g_shift = -8, x = 1; x < g_mask; x = x << 1)
         g_shift++;

     for (b_shift = -8, x = 1; x < b_mask; x = x << 1)
         b_shift++;

     shiftmask_fl = 1;
}

// Called by UploadNewPalette()
unsigned long xlib_rgb24 (int r, int g, int b)
{
     unsigned long p;

     if (shiftmask_fl == 0)
         shiftmask_init();

     p = 0;

     if (r_shift > 0) {
         p = (r << (r_shift)) & r_mask;
     } else if (r_shift < 0) {
         p = (r >> (-r_shift)) & r_mask;
     } else p |= (r & r_mask);

     if (g_shift > 0) {
         p |= (g << (g_shift)) & g_mask;
     } else if (g_shift < 0) {
         p |= (g >> (-g_shift)) & g_mask;
     } else p |= (g & g_mask);

     if (b_shift > 0) {
         p |= (b << (b_shift)) & b_mask;
     } else if (b_shift < 0) {
         p |=(b >> (-b_shift)) & b_mask;
     } else p |= (b & b_mask);

     return p;
}

//
// Palette stuff.
//
void UploadNewPalette (Colormap cmap, byte *palette)
{
     (void)cmap; // UNUSED
     for (int i = 0; i < 256; i++)
     {
         st2d_8to24table[i] = xlib_rgb24(palette[i * 3], palette[i * 3 + 
1],palette[i * 3 + 2]);
     }
}

//
// I_SetPalette
//
void I_SetPalette (byte* palette)
{
     UploadNewPalette(X_cmap, palette);
}

//
// I_FinishUpdate
//
// Display the image on the window
void I_FinishUpdate (void)
{
     // Convert colors of the image to 24 bits color depth
     st3_fixup(X_width, X_height);

     // draw the image
     XPutImage(X_display,
               X_mainWindow,
               X_gc,
               image,
               0, 0,
               0, 0,
               X_width, X_height );

     // sync up with server
     XSync(X_display, False);
}



More information about the xorg mailing list