From b5c4bf8b5fb124a63b430f83943d5e46711b6c1c Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Thu, 8 Feb 2018 21:37:17 +0000
Subject: [PATCH] Proper fix for palette modification.

---
 src/conio/bitmap_con.c | 13 +++++++++++--
 src/conio/bitmap_con.h |  2 +-
 src/conio/ciolib.c     | 16 +++++++++++++---
 src/conio/ciolib.h     |  9 ++++++---
 src/conio/cterm.c      |  4 +++-
 5 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/src/conio/bitmap_con.c b/src/conio/bitmap_con.c
index ef48b3b27f..a5a582bc64 100644
--- a/src/conio/bitmap_con.c
+++ b/src/conio/bitmap_con.c
@@ -1572,16 +1572,25 @@ struct ciolib_pixels *bitmap_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, ui
 	return pixels;
 }
 
-uint32_t *bitmap_get_modepalette(void)
+uint32_t *bitmap_get_modepalette(uint32_t p[16])
 {
 	uint32_t *ret;
 
 	pthread_mutex_lock(&vstatlock);
-	ret = vstat.palette;
+	memcpy(p, vstat.palette, sizeof(vstat.palette));
+	ret = p;
 	pthread_mutex_unlock(&vstatlock);
 	return ret;
 }
 
+int bitmap_set_modepalette(uint32_t p[16])
+{
+	pthread_mutex_lock(&vstatlock);
+	memcpy(vstat.palette, p, sizeof(vstat.palette));
+	pthread_mutex_unlock(&vstatlock);
+	return 0;
+}
+
 /***********************/
 /* Called from drivers */
 /***********************/
diff --git a/src/conio/bitmap_con.h b/src/conio/bitmap_con.h
index bbe6b90c4a..8edebbe6d9 100644
--- a/src/conio/bitmap_con.h
+++ b/src/conio/bitmap_con.h
@@ -28,7 +28,7 @@ int bitmap_attr2palette(uint8_t attr, uint32_t *fgp, uint32_t *bgp);
 int bitmap_setpixel(uint32_t x, uint32_t y, uint32_t colour);
 int bitmap_setpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey, uint32_t x_off, uint32_t y_off, struct ciolib_pixels *, void *mask);
 struct ciolib_pixels *bitmap_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
-uint32_t *bitmap_get_modepalette(void);
+uint32_t *bitmap_get_modepalette(uint32_t p[16]);
 #endif
 
 #ifdef BITMAP_CIOLIB_DRIVER
diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c
index eb65820911..937c868f15 100644
--- a/src/conio/ciolib.c
+++ b/src/conio/ciolib.c
@@ -134,7 +134,8 @@ CIOLIBEXPORT struct ciolib_screen * CIOLIBCALL ciolib_savescreen(void);
 CIOLIBEXPORT void CIOLIBCALL ciolib_freescreen(struct ciolib_screen *);
 CIOLIBEXPORT int CIOLIBCALL ciolib_restorescreen(struct ciolib_screen *scrn);
 CIOLIBEXPORT void CIOLIBCALL ciolib_setcolour(uint32_t fg, uint32_t bg);
-CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(void);
+CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(uint32_t p[16]);
+CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t p[16]);
 
 #if defined(WITH_SDL) || defined(WITH_SDL_AUDIO)
 int sdl_video_initialized = 0;
@@ -1890,11 +1891,20 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_setcolour(uint32_t fg, uint32_t bg)
 	ciolib_bg = bg;
 }
 
-CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(void)
+CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(uint32_t p[16])
 {
 	CIOLIB_INIT();
 
 	if (cio_api.get_modepalette)
-		return cio_api.get_modepalette();
+		return cio_api.get_modepalette(p);
 	return NULL;
 }
+
+CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t p[16])
+{
+	CIOLIB_INIT();
+
+	if (cio_api.set_modepalette)
+		return cio_api.set_modepalette(p);
+	return 0;
+}
diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h
index 804a9de116..60e100b9b5 100644
--- a/src/conio/ciolib.h
+++ b/src/conio/ciolib.h
@@ -360,7 +360,8 @@ typedef struct {
 	int		(*setpixel)	(uint32_t x, uint32_t y, uint32_t colour);
 	struct ciolib_pixels *(*getpixels)(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
 	int		(*setpixels)(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey, uint32_t x_off, uint32_t y_off, struct ciolib_pixels *pixels, void *mask);
-	uint32_t 	*(*get_modepalette)(void);
+	uint32_t 	*(*get_modepalette)(uint32_t[16]);
+	int	(*set_modepalette)(uint32_t[16]);
 } cioapi_t;
 
 CIOLIBEXPORTVAR cioapi_t cio_api;
@@ -448,7 +449,8 @@ CIOLIBEXPORT struct ciolib_screen * CIOLIBCALL ciolib_savescreen(void);
 CIOLIBEXPORT void CIOLIBCALL ciolib_freescreen(struct ciolib_screen *);
 CIOLIBEXPORT int CIOLIBCALL ciolib_restorescreen(struct ciolib_screen *scrn);
 CIOLIBEXPORT void CIOLIBCALL ciolib_setcolour(uint32_t fg, uint32_t bg);
-CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(void);
+CIOLIBEXPORT uint32_t * CIOLIBCALL ciolib_get_modepalette(uint32_t[16]);
+CIOLIBEXPORT int CIOLIBCALL ciolib_set_modepalette(uint32_t[16]);
 
 /* DoorWay specific stuff that's only applicable to ANSI mode. */
 CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
@@ -524,7 +526,8 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
 	#define freescreen(a)			ciolib_freescreen(a)
 	#define restorescreen(a)		ciolib_restorescreen(a)
 	#define setcolour(a,b)			ciolib_setcolour(a,b)
-	#define get_modepalette()		ciolib_get_modepalette()
+	#define get_modepalette(a)		ciolib_get_modepalette(a)
+	#define set_modepalette(a)		ciolib_set_modepalette(a)
 #endif
 
 #ifdef WITH_SDL
diff --git a/src/conio/cterm.c b/src/conio/cterm.c
index aa527644ed..f8ab144751 100644
--- a/src/conio/cterm.c
+++ b/src/conio/cterm.c
@@ -3024,13 +3024,14 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void *
 	int	olddmc;
 	int oldptnm;
 	uint32_t *mpalette;
+	uint32_t palette[16];
 
 	if(!cterm->started)
 		cterm_start(cterm);
 
 	/* Now rejigger the current modes palette... */
 	/* TODO: We need a way to remap instead of fuckery */
-	mpalette = get_modepalette();
+	mpalette = get_modepalette(palette);
 	if (mpalette) {
 		for (i=0; i < 16; i++) {
 			mpalette[i] += 16;
@@ -3764,6 +3765,7 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void *
 	if (mpalette) {
 		for (i=0; i < 16; i++)
 			mpalette[i] -= 16;
+		set_modepalette(mpalette);
 	}
 
 	return(retbuf);
-- 
GitLab