Commit c4053695 authored by deuce's avatar deuce
Browse files

Add new functions:

struct ciolib_pixels *getpixels(sx, sy, ex, ey)
Returns and allocated array of pixels suitable for use by setpixels()
Must be freed using freepixels()

freepixles(struct ciolib_pixels *)
Frees a struct ciolib_pixels returned by getpixels()

setpixels(sx, sy, ex, ey, x_off, y_off, pixels)
Draws the pixels on the screen. x/y_off are an offset in the pixel array

struct ciolib_screen *savescreen()
Saves the entire current screen state.

freescreen(a)
Frees a value returned by savescreen()

restorescreen(a)
Restores the entire screen state

This allows SyncTERM to not crap all over Sixel graphics.
parent d20a8bba
......@@ -1202,3 +1202,70 @@ int bitmap_setpixel(uint32_t x, uint32_t y, uint32_t colour)
pthread_mutex_unlock(&screenlock);
return 1;
}
struct ciolib_pixels *bitmap_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey)
{
struct ciolib_pixels *pixels;
uint32_t width,height;
size_t y;
if (sx > ex || sy > ey)
return NULL;
if (ex > screenwidth || ey > screenheight)
return NULL;
width = ex - sx + 1;
height = ey - sy + 1;
pixels = malloc(sizeof(*pixels));
if (pixels == NULL)
return NULL;
pixels->width = width;
pixels->height = height;
pixels->pixels = malloc(sizeof(pixels->pixels[0])*(width)*(height));
if (pixels->pixels == NULL) {
free(pixels);
return NULL;
}
pthread_mutex_lock(&screenlock);
for (y = sy; y <= ey; y++)
memcpy(&pixels->pixels[width*(y-sy)], &screen[PIXEL_OFFSET(sx, y)], width * sizeof(pixels->pixels[0]));
pthread_mutex_unlock(&screenlock);
return pixels;
}
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 *pixels)
{
uint32_t y;
uint32_t width,height;
if (pixels == NULL)
return 0;
if (sx > ex || sy > ey)
return 0;
if (ex > screenwidth || ey > screenheight)
return 0;
width = ex - sx + 1;
height = ey - sy + 1;
if (width + x_off > pixels->width)
return 0;
if (height + y_off > pixels->height)
return 0;
pthread_mutex_lock(&screenlock);
for (y = sy; y <= ey; y++)
memcpy(&screen[PIXEL_OFFSET(sx, y)], &pixels->pixels[pixels->width*(y-sy+y_off)+x_off], width * sizeof(pixels->pixels[0]));
pthread_mutex_unlock(&screenlock);
update_pixels++;
return 1;
}
......@@ -34,5 +34,7 @@ void bitmap_setscaling(int new_value);
int bitmap_getscaling(void);
int bitmap_attr2palette(uint8_t attr, uint32_t *fgp, uint32_t *bgp);
int bitmap_setpixel(uint32_t x, uint32_t y, uint32_t colour);
struct ciolib_pixels *bitmap_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
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 *);
#endif
......@@ -125,6 +125,12 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cputch(uint32_t fg_palette, uint32_t bg_palet
CIOLIBEXPORT int CIOLIBCALL ciolib_ccputs(uint32_t fg_palette, uint32_t bg_palette, const char *str);
CIOLIBEXPORT int CIOLIBCALL ciolib_attr2palette(uint8_t attr, uint32_t *fg, uint32_t *bg);
CIOLIBEXPORT int CIOLIBCALL ciolib_setpixel(uint32_t x, uint32_t y, uint32_t colour);
CIOLIBEXPORT struct ciolib_pixels * CIOLIBCALL ciolib_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
CIOLIBEXPORT int CIOLIBCALL ciolib_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);
CIOLIBEXPORT void CIOLIBCALL ciolib_freepixels(struct ciolib_pixels *pixels);
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);
#if defined(WITH_SDL) || defined(WITH_SDL_AUDIO)
int sdl_video_initialized = 0;
......@@ -174,6 +180,8 @@ int try_sdl_init(int mode)
cio_api.setpalette=sdl_setpalette;
cio_api.attr2palette=bitmap_attr2palette;
cio_api.setpixel=bitmap_setpixel;
cio_api.getpixels=bitmap_getpixels;
cio_api.setpixels=bitmap_setpixels;
return(1);
}
return(0);
......@@ -224,6 +232,7 @@ int try_x_init(int mode)
cio_api.setpalette=x_setpalette;
cio_api.attr2palette=bitmap_attr2palette;
cio_api.setpixel=bitmap_setpixel;
cio_api.setpixels=bitmap_setpixels;
return(1);
}
return(0);
......@@ -1753,3 +1762,100 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_setpixel(uint32_t x, uint32_t y, uint32_t col
return cio_api.setpixel(x, y, colour);
return 0;
}
CIOLIBEXPORT struct ciolib_pixels * CIOLIBCALL ciolib_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey)
{
CIOLIB_INIT();
if (cio_api.getpixels)
return cio_api.getpixels(sx, sy, ex, ey);
return NULL;
}
CIOLIBEXPORT int CIOLIBCALL ciolib_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)
{
CIOLIB_INIT();
if (cio_api.setpixels)
return cio_api.setpixels(sx, sy, ex, ey, x_off, y_off, pixels);
return 0;
}
CIOLIBEXPORT void CIOLIBCALL ciolib_freepixels(struct ciolib_pixels *pixels)
{
if (pixels == NULL)
return;
FREE_AND_NULL(pixels->pixels);
FREE_AND_NULL(pixels);
}
CIOLIBEXPORT struct ciolib_screen * CIOLIBCALL ciolib_savescreen(void)
{
struct ciolib_screen *ret;
int vmode;
CIOLIB_INIT();
ret = malloc(sizeof(*ret));
if (ret == NULL)
return NULL;
ciolib_gettextinfo(&ret->text_info);
vmode = find_vmode(ret->text_info.currmode);
ret->vmem = malloc(vparams[vmode].cols * vparams[vmode].rows * 2);
if (ret->vmem == NULL) {
free(ret);
return NULL;
}
ret->foreground = malloc(vparams[vmode].cols * vparams[vmode].rows * sizeof(ret->foreground[0]));
if (ret->foreground == NULL) {
free(ret->vmem);
free(ret);
return NULL;
}
ret->background = malloc(vparams[vmode].cols * vparams[vmode].rows * sizeof(ret->background[0]));
if (ret->background == NULL) {
free(ret->foreground);
free(ret->vmem);
free(ret);
return NULL;
}
ret->pixels = ciolib_getpixels(0, 0, vparams[vmode].charwidth * vparams[vmode].cols, vparams[vmode].charheight * vparams[vmode].rows);
ciolib_pgettext(1, 1, vparams[vmode].cols, vparams[vmode].rows, ret->vmem, ret->foreground, ret->background);
return ret;
}
CIOLIBEXPORT void CIOLIBCALL ciolib_freescreen(struct ciolib_screen *scrn)
{
if (scrn == NULL)
return;
ciolib_freepixels(scrn->pixels);
FREE_AND_NULL(scrn->background);
FREE_AND_NULL(scrn->foreground);
FREE_AND_NULL(scrn->vmem);
free(scrn);
}
CIOLIBEXPORT int CIOLIBCALL ciolib_restorescreen(struct ciolib_screen *scrn)
{
struct text_info ti;
int vmode;
CIOLIB_INIT();
ciolib_gettextinfo(&ti);
if (ti.currmode != scrn->text_info.currmode)
ciolib_textmode(scrn->text_info.currmode);
ciolib_pputtext(1, 1, scrn->text_info.screenwidth, scrn->text_info.screenheight, scrn->vmem, scrn->foreground, scrn->background);
ciolib_gotoxy(scrn->text_info.curx, scrn->text_info.cury);
ciolib_textcolor(scrn->text_info.attribute);
ciolib_window(scrn->text_info.winleft, scrn->text_info.wintop, scrn->text_info.winright, scrn->text_info.winbottom);
vmode = find_vmode(scrn->text_info.currmode);
ciolib_setpixels(0, 0, vparams[vmode].charwidth * vparams[vmode].cols, vparams[vmode].charheight * vparams[vmode].rows, 0, 0, scrn->pixels);
return 1;
}
......
......@@ -252,6 +252,20 @@ struct conio_font_data_struct {
CIOLIBEXPORTVAR struct conio_font_data_struct conio_fontdata[257];
struct ciolib_pixels {
uint32_t *pixels;
uint32_t width;
uint32_t height;
};
struct ciolib_screen {
struct ciolib_pixels *pixels;
void *vmem;
void *foreground;
void *background;
struct text_info text_info;
};
#define CONIO_FIRST_FREE_FONT 43
typedef struct {
......@@ -319,6 +333,8 @@ typedef struct {
int (*setpalette) (uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
int (*attr2palette) (uint8_t attr, uint32_t *fg, uint32_t *bg);
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);
} cioapi_t;
CIOLIBEXPORTVAR cioapi_t cio_api;
......@@ -394,6 +410,13 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getscaling(void);
CIOLIBEXPORT int CIOLIBCALL ciolib_setpalette(uint32_t entry, uint16_t r, uint16_t g, uint16_t b);
CIOLIBEXPORT int CIOLIBCALL ciolib_attr2palette(uint8_t attr, uint32_t *fg, uint32_t *bg);
CIOLIBEXPORT int CIOLIBCALL ciolib_setpixel(uint32_t x, uint32_t y, uint32_t colour);
CIOLIBEXPORT struct ciolib_pixels * CIOLIBCALL ciolib_getpixels(uint32_t sx, uint32_t sy, uint32_t ex, uint32_t ey);
CIOLIBEXPORT int CIOLIBCALL ciolib_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);
CIOLIBEXPORT void CIOLIBCALL ciolib_freepixels(struct ciolib_pixels *pixels);
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);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
......@@ -462,6 +485,12 @@ CIOLIBEXPORT void CIOLIBCALL ansi_ciolib_setdoorway(int enable);
#define setpalette(e,r,g,b) ciolib_setpalette(e,r,g,b)
#define attr2palette(a,b,c) ciolib_attr2palette(a,b,c)
#define setpixel(a,b,c) ciolib_setpixel(a,b,c)
#define getpixels(a,b,c,d) ciolib_getpixels(a,b,c,d)
#define setpixels(a,b,c,d,e,f,g) ciolib_setpixels(a,b,c,d,e,f,g)
#define freepixles(a) ciolib_freepixels(a)
#define savescreen() ciolib_savescreen()
#define freescreen(a) ciolib_freescreen(a)
#define restorescreen(a) ciolib_restorescreen(a)
#endif
#ifdef WITH_SDL
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment