59 #include <X11/Xutil.h>
63 #define FB_TICK_SHIFT 19
78 for (i=0; i<256; i++) {
79 gray = 255*i/(ncolors-1);
96 for (i=0; i<256; i++) {
105 static void set_title(
struct vfb_data *d)
107 snprintf(d->
title,
sizeof(d->
title),
"GXemul: %ix%ix%i %s framebuffer",
125 unsigned char *new_framebuffer;
126 int y, new_bytes_per_line;
130 fatal(
"dev_fb_resize(): d == NULL\n");
134 if (new_xsize < 10 || new_ysize < 10) {
135 fatal(
"dev_fb_resize(): size too small.\n");
139 new_bytes_per_line = new_xsize * d->
bit_depth / 8;
140 size = new_ysize * new_bytes_per_line;
146 for (y=0; y<new_ysize; y++) {
148 size_t toofs = new_bytes_per_line * y;
151 : new_bytes_per_line;
152 memset(new_framebuffer + toofs, 0, new_bytes_per_line);
153 if (y < d->x11_ysize)
154 memmove(new_framebuffer + toofs,
164 if (new_xsize > d->
xsize || new_ysize > d->
ysize) {
194 int cursor_xsize,
int cursor_ysize)
200 if (cursor_x + cursor_xsize >= d->
xsize)
201 cursor_x = d->
xsize - cursor_xsize;
202 if (cursor_y + cursor_ysize >= d->
ysize)
203 cursor_y = d->
ysize - cursor_ysize;
235 int fill_g,
int fill_b,
int x1,
int y1,
int x2,
int y2,
236 int from_x,
int from_y)
239 size_t from_ofs, dest_ofs, linelen;
242 debug(
"framebuffer_blockcopyfill(FILL, %i,%i, %i,%i, "
243 "color %i,%i,%i)\n", x1,y1, x2,y2, fill_r, fill_g, fill_b);
245 debug(
"framebuffer_blockcopyfill(COPY, %i,%i, %i,%i, from "
246 "%i,%i)\n", x1,y1, x2,y2, from_x,from_y);
255 linelen = (x2-x1 + 1) * (d->
bit_depth/8);
259 for (y=y1; y<=y2; y++) {
260 if (y>=0 && y<d->ysize) {
265 for (x=0; x<(ssize_t)linelen && x <
266 (
int)
sizeof(
buf); x += 3) {
272 memset(
buf, fill_r, linelen);
274 fatal(
"Unimplemented bit-depth (%i)"
285 for (y=y1; y<=y2; y++) {
286 if (y >= 0 && y < d->ysize) {
287 if (from_y >= 0 && from_y < d->ysize)
314 #define REDRAW redraw_fallback
319 #define REDRAW redraw_24
324 #define REDRAW redraw_16
329 #define REDRAW redraw_15
336 #define REDRAW redraw_24_bo
341 #define REDRAW redraw_16_bo
346 #define REDRAW redraw_15_bo
354 #define REDRAW redraw_fallback_sd
359 #define REDRAW redraw_24_sd
364 #define REDRAW redraw_16_sd
369 #define REDRAW redraw_15_sd
376 #define REDRAW redraw_24_bo_sd
381 #define REDRAW redraw_16_bo_sd
386 #define REDRAW redraw_15_bo_sd
392 void (*redraw[2 * 4 * 2])(
struct vfb_data *, int, int) = {
393 redraw_fallback, redraw_fallback,
394 redraw_15, redraw_15_bo,
395 redraw_16, redraw_16_bo,
396 redraw_24, redraw_24_bo,
397 redraw_fallback_sd, redraw_fallback_sd,
398 redraw_15_sd, redraw_15_bo_sd,
399 redraw_16_sd, redraw_16_bo_sd,
400 redraw_24_sd, redraw_24_bo_sd };
409 int need_to_flush_x11 = 0;
410 int need_to_redraw_cursor = 0;
417 uint64_t high, low = (uint64_t)(int64_t) -1;
422 if ((int64_t)low == -1)
489 need_to_redraw_cursor = 1;
510 need_to_redraw_cursor = 1;
513 if (need_to_redraw_cursor) {
573 need_to_flush_x11 = 1;
581 if (need_to_redraw_cursor) {
593 need_to_flush_x11 = 1;
599 if (need_to_flush_x11)
605 This is a hack used to produce raw ppm image dumps, which can then be
606 used to make movies, e.g. http:
609 static struct timeval tv_last;
610 static bool first =
true;
613 gettimeofday(&tv, NULL);
622 double diff = (tv.tv_sec - tv_last.tv_sec) + (tv.tv_usec - tv_last.tv_usec) / 1000000.0;
625 static int outputNr = 0;
630 snprintf(name,
sizeof(name),
"gxemul-%06i.ppm", outputNr);
632 FILE *
f = fopen(name,
"w");
639 const int xsize = 640;
640 const int ysize = 480;
641 fprintf(
f,
"P6\n%i %i\n255\n", xsize, ysize);
642 unsigned char buf[xsize*ysize*3];
643 memset(buf, 0, xsize*ysize*3);
662 int r = 0, g = 0, b = 0, n = 0;
663 for (
int suby = 0; suby < scaledown; ++suby)
664 for (
int subx = 0; subx < scaledown; ++subx)
667 int rx = x * scaledown + subx;
668 int ry = y * scaledown + suby;
683 r /= n; g /= n; b /= n;
684 int j = (y + yofs) * xsize + x + xofs;
690 fwrite(buf, 1, xsize*ysize*3,
f);
711 fatal(
"[ dev_fb: write to addr=%08lx, data = ",
712 (
long)relative_addr);
713 for (i=0; i<len; i++)
717 fatal(
"[ dev_fb: read from addr=%08lx, data = ",
718 (
long)relative_addr);
719 for (i=0; i<len; i++)
730 for (i=0; i<len; i++) {
796 for (i=0; i<len; i++)
803 for (i=0; i<len; i++)
841 int reverse_start = 0;
845 memset(d, 0,
sizeof(
struct vfb_data));
911 memset(d->
framebuffer, reverse_start? 255 : 0, size);
936 case 15: i = 2;
break;
937 case 16: i = 4;
break;
938 case 24: i = 6;
break;
952 snprintf(name2, nlen,
"fb [%s]",
name);
955 if ((baseaddr & 0xfff) == 0)