Skip to content
Snippets Groups Projects
Commit aaccacf4 authored by deuce's avatar deuce
Browse files

Add support for setpalette(uint32_t index, uint16_t r, g, b)

This sets a specific palette entry to the 48-bit colour specified.
Psychadelic palette shifting is now possible (X11 mode only so far).
parent 5749579a
No related branches found
No related tags found
No related merge requests found
......@@ -118,6 +118,7 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_get_window_info(int *width, int *height, int *xpos, int *ypos);
CIOLIBEXPORT void CIOLIBCALL ciolib_setscaling(int new_value);
CIOLIBEXPORT int CIOLIBCALL ciolib_getscaling(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
#if defined(WITH_SDL) || defined(WITH_SDL_AUDIO)
int sdl_video_initialized = 0;
......@@ -209,6 +210,7 @@ int try_x_init(int mode)
cio_api.get_window_info=x_get_window_info;
cio_api.setscaling=bitmap_setscaling;
cio_api.getscaling=bitmap_getscaling;
cio_api.setpalette=x_setpalette;
return(1);
}
return(0);
......@@ -1574,3 +1576,11 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getscaling(void)
return(cio_api.getscaling());
return(1);
}
/* Optional */
CIOLIBEXPORT int CIOLIBCALL ciolib_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b)
{
if(cio_api.setpalette)
return(cio_api.setpalette(entry, r, g, b));
return(1);
}
......
......@@ -35,6 +35,7 @@
#define _CIOLIB_H_
#include <string.h> /* size_t */
#include "gen_defs.h"
#ifdef CIOLIBEXPORT
#undef CIOLIBEXPORT
......@@ -311,6 +312,7 @@ typedef struct {
void (*setscaling) (int new_value);
int (*getscaling) (void);
int *ESCDELAY;
int (*setpalette) (uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
} cioapi_t;
CIOLIBEXPORTVAR cioapi_t cio_api;
......@@ -379,6 +381,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_setvideoflags(int flags);
CIOLIBEXPORT int CIOLIBCALL ciolib_getvideoflags(void);
CIOLIBEXPORT void CIOLIBCALL ciolib_setscaling(int flags);
CIOLIBEXPORT int CIOLIBCALL ciolib_getscaling(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
......@@ -440,6 +443,7 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
#define getvideoflags() ciolib_getvideoflags()
#define setscaling(a) ciolib_setscaling(a)
#define getscaling() ciolib_getscaling()
#define setpalette(e,r,g,b) ciolib_setpalette(e,r,g,b)
#endif
#ifdef WITH_SDL
......
......@@ -152,6 +152,19 @@ int x_get_window_info(int *width, int *height, int *xpos, int *ypos)
return(0);
}
int x_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b)
{
struct x11_local_event ev;
ev.type=X11_LOCAL_SETPALETTE;
ev.data.palette.index = entry;
ev.data.palette.r = r;
ev.data.palette.g = g;
ev.data.palette.b = b;
while(write(local_pipe[1], &ev, sizeof(ev))==-1);
return(0);
}
/* Mouse event/keyboard thread */
void x11_mouse_thread(void *data)
{
......@@ -360,6 +373,10 @@ int x_init(void)
xp_dlclose(dl);
return(-1);
}
if((x11.XFreeColors=xp_dlsym(dl,XFreeColors))==NULL) {
xp_dlclose(dl);
return(-1);
}
if(sem_init(&pastebuf_set, 0, 0)) {
xp_dlclose(dl);
......
......@@ -69,6 +69,7 @@ char *x_getcliptext(void);
int x_setfont(int font, int force);
int x_getfont(void);
int x_loadfont(char *filename);
int x_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
int x_get_window_info(int *width, int *height, int *xpos, int *ypos);
void x11_drawrect(int xoffset,int yoffset,int width,int height,unsigned char *data);
void x11_flush(void);
......
......@@ -71,7 +71,7 @@ static int old_scaling = 0;
/* Array of Graphics Contexts */
static GC gca[sizeof(dac_default)/sizeof(struct dac_colors)];
static GC *gca = NULL;
/* Array of pixel values to match all possible colours */
static unsigned long *pixel = NULL;
......@@ -235,6 +235,7 @@ static int init_window()
if (pixelsz < sizeof(dac_default)/sizeof(struct dac_colors)) {
unsigned long *newpixel;
GC *newgca;
size_t newpixelsz = sizeof(dac_default)/sizeof(struct dac_colors);
newpixel = realloc(pixel, sizeof(pixel[0])*newpixelsz);
......@@ -242,6 +243,10 @@ static int init_window()
return -1;
pixel = newpixel;
pixelsz = newpixelsz;
newgca = realloc(gca, sizeof(gca[0])*newpixelsz);
if (newgca == NULL)
return -1;
gca = newgca;
}
/* Get the pixel and GC values */
for(i=0; i<sizeof(dac_default)/sizeof(struct dac_colors); i++) {
......@@ -889,6 +894,59 @@ static void x11_terminate_event_thread(void)
sem_wait(&event_thread_complete);
}
static void local_set_palette(struct x11_palette_entry *p)
{
unsigned long *newpixel;
struct GC *newgca;
size_t i;
size_t newpixelsz;
XGCValues gcv;
XColor color;
gcv.function = GXcopy;
gcv.foreground = white;
gcv.background = black;
gcv.graphics_exposures = False;
newpixelsz = p->index + 1;
if (pixelsz < newpixelsz) {
newpixel = realloc(pixel, sizeof(pixel[0])*newpixelsz);
if (newpixel == NULL)
// TODO: Handle failure!
return;
pixel = newpixel;
newgca = realloc(gca, sizeof(gca[0])*newpixelsz);
if (newgca == NULL)
// TODO: Handle failure!
return;
gca = newgca;
/* Set all empty colours to black. */
for (i = pixelsz; i < (newpixelsz-1); i++) {
color.red=0;
color.green=0;
color.blue=0;
if(x11.XAllocColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &color))
pixel[i]=color.pixel;
gcv.foreground=color.pixel;
gca[i]=x11.XCreateGC(dpy, win, GCFunction | GCForeground | GCBackground | GCGraphicsExposures, &gcv);
}
pixelsz = newpixelsz;
}
else {
/* Free old colour first */
x11.XFreeColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &pixel[p->index], 1, 0);
}
/* Now set new colour */
color.red=p->r;
color.green=p->g;
color.blue=p->b;
if(x11.XAllocColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &color))
pixel[p->index]=color.pixel;
gcv.foreground=color.pixel;
gca[p->index]=x11.XCreateGC(dpy, win, GCFunction | GCForeground | GCBackground | GCGraphicsExposures, &gcv);
expose_rect(0, 0, x11_window_width-1, x11_window_height-1);
}
void x11_event_thread(void *args)
{
int x;
......@@ -1005,6 +1063,9 @@ void x11_event_thread(void *args)
case X11_LOCAL_BEEP:
x11.XBell(dpy, 100);
break;
case X11_LOCAL_SETPALETTE:
local_set_palette(&lev.data.palette);
break;
}
tv.tv_sec=0;
tv.tv_usec=0;
......
......@@ -23,6 +23,14 @@ enum x11_local_events {
,X11_LOCAL_DRAWRECT
,X11_LOCAL_FLUSH
,X11_LOCAL_BEEP
,X11_LOCAL_SETPALETTE
};
struct x11_palette_entry {
uint32_t index;
uint16_t r;
uint16_t g;
uint16_t b;
};
struct x11_local_event {
......@@ -31,7 +39,8 @@ struct x11_local_event {
int mode;
char name[81];
char title[81];
struct update_rect rect;
struct update_rect rect;
struct x11_palette_entry palette;
} data;
};
......@@ -83,6 +92,7 @@ struct x11 {
void (*XSetWMProperties) (Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
Status (*XSetWMProtocols) (Display*, Window, Atom *, int);
Atom (*XInternAtom) (Display *, char *, Bool);
int (*XFreeColors) (Display*, Colormap, unsigned long *, int, unsigned long);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment