/[gxemul]/trunk/src/devices/dev_fb.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_fb.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_fb.c,v 1.107 2005/09/18 19:54:15 debug Exp $   *  $Id: dev_fb.c,v 1.123 2006/07/24 08:08:39 debug Exp $
29   *     *  
30   *  Generic framebuffer device.   *  Generic framebuffer device.
31   *   *
32   *      DECstation VFB01 monochrome framebuffer, 1024x864   *      DECstation VFB01 monochrome framebuffer, 1024x864
33   *      DECstation VFB02 8-bit color framebuffer, 1024x864   *      DECstation VFB02 8-bit color framebuffer, 1024x864
34   *      DECstation Maxine, 1024x768 8-bit color   *      DECstation Maxine, 1024x768 8-bit color
35   *      HPCmips framebuffer   *      HPC (mips, arm, ..) framebuffer
36   *      Playstation 2 (24-bit color)   *      Playstation 2 (24-bit color)
37   *      generic (any resolution, several bit depths possible)   *      Generic (any resolution, several bit depths possible, useful for
38     *              testmachines)
39   *   *
40   *   *
41   *  TODO:  There is still a bug when redrawing the cursor. The underlying   *  TODO:  This should actually be independent of X11, but that
  *         image is moved 1 pixel (?), or something like that.  
  *  
  *  TODO:  This should actually be independant of X11, but that  
42   *         might be too hard to do right now.   *         might be too hard to do right now.
43   *   *
44   *  TODO:  playstation 2 pixels are stored in another format, actually   *  TODO:  playstation 2 pixels are stored in another format, actually
# Line 107  void set_blackwhite_palette(struct vfb_d Line 105  void set_blackwhite_palette(struct vfb_d
105  }  }
106    
107    
108    static void set_title(struct vfb_data *d)
109    {
110            snprintf(d->title, sizeof(d->title),"GXemul: %ix%ix%i %s framebuffer",
111                d->visible_xsize, d->visible_ysize, d->bit_depth, d->name);
112            d->title[sizeof(d->title)-1] = '\0';
113    }
114    
115    
116  /*  /*
117   *  dev_fb_resize():   *  dev_fb_resize():
118   *   *
119   *  Resize a framebuffer window. (This functionality is probably a bit buggy,   *  Resize a framebuffer window. (This functionality is probably a bit buggy,
120   *  because I didn't think of including it from the start.)   *  because I didn't think of including it from the start.)
121     *
122     *  SUPER-IMPORTANT: Anyone who resizes a framebuffer by calling this function
123     *  must also clear all dyntrans address translations manually, in all cpus
124     *  which might have access to the framebuffer!
125   */   */
126  void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)  void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)
127  {  {
# Line 124  void dev_fb_resize(struct vfb_data *d, i Line 134  void dev_fb_resize(struct vfb_data *d, i
134                  return;                  return;
135          }          }
136    
137            if (new_xsize < 10 || new_ysize < 10) {
138                    fatal("dev_fb_resize(): size too small.\n");
139                    exit(1);
140            }
141    
142          new_bytes_per_line = new_xsize * d->bit_depth / 8;          new_bytes_per_line = new_xsize * d->bit_depth / 8;
143          size = new_ysize * new_bytes_per_line;          size = new_ysize * new_bytes_per_line;
144    
# Line 153  void dev_fb_resize(struct vfb_data *d, i Line 168  void dev_fb_resize(struct vfb_data *d, i
168          d->framebuffer = new_framebuffer;          d->framebuffer = new_framebuffer;
169          d->framebuffer_size = size;          d->framebuffer_size = size;
170    
171          if (new_xsize > d->x11_xsize || new_ysize > d->x11_ysize) {          if (new_xsize > d->xsize || new_ysize > d->ysize) {
172                  d->update_x1 = d->update_y1 = 0;                  d->update_x1 = d->update_y1 = 0;
173                  d->update_x2 = new_xsize - 1;                  d->update_x2 = new_xsize - 1;
174                  d->update_y2 = new_ysize - 1;                  d->update_y2 = new_ysize - 1;
175          }          }
176    
177          d->bytes_per_line = new_bytes_per_line;          d->bytes_per_line = new_bytes_per_line;
178          d->x11_xsize = d->visible_xsize = new_xsize;          d->xsize = d->visible_xsize = new_xsize;
179          d->x11_ysize = d->visible_ysize = new_ysize;          d->ysize = d->visible_ysize = new_ysize;
180    
181            d->x11_xsize = d->xsize / d->vfb_scaledown;
182            d->x11_ysize = d->ysize / d->vfb_scaledown;
183    
184            memory_device_update_data(d->memory, d, d->framebuffer);
185    
186            set_title(d);
187    
188  #ifdef WITH_X11  #ifdef WITH_X11
189          if (d->fb_window != NULL)          if (d->fb_window != NULL) {
190                  x11_fb_resize(d->fb_window, new_xsize, new_ysize);                  x11_fb_resize(d->fb_window, new_xsize, new_ysize);
191                    x11_set_standard_properties(d->fb_window, d->title);
192            }
193  #endif  #endif
194  }  }
195    
# Line 211  void dev_fb_setcursor(struct vfb_data *d Line 235  void dev_fb_setcursor(struct vfb_data *d
235   *  block copy/fill.   *  block copy/fill.
236   *   *
237   *  If fillflag is non-zero, then fill_[rgb] should contain the color   *  If fillflag is non-zero, then fill_[rgb] should contain the color
238   *  with which to fill.   *  with which to fill. (In 8-bit mode, only fill_r is used.)
239   *   *
240   *  If fillflag is zero, copy mode is used, and from_[xy] should contain   *  If fillflag is zero, copy mode is used, and from_[xy] should contain
241   *  the offset on the framebuffer where we should copy from.   *  the offset on the framebuffer where we should copy from.
# Line 222  void framebuffer_blockcopyfill(struct vf Line 246  void framebuffer_blockcopyfill(struct vf
246          int fill_g, int fill_b, int x1, int y1, int x2, int y2,          int fill_g, int fill_b, int x1, int y1, int x2, int y2,
247          int from_x, int from_y)          int from_x, int from_y)
248  {  {
249          int y;          int x, y;
250          long from_ofs, dest_ofs, linelen;          long from_ofs, dest_ofs, linelen;
251    
252          if (fillflag)          if (fillflag)
# Line 245  void framebuffer_blockcopyfill(struct vf Line 269  void framebuffer_blockcopyfill(struct vf
269          if (fillflag) {          if (fillflag) {
270                  for (y=y1; y<=y2; y++) {                  for (y=y1; y<=y2; y++) {
271                          if (y>=0 && y<d->ysize) {                          if (y>=0 && y<d->ysize) {
272                                  int x;                                  unsigned char *buf =
273                                  char buf[8192 * 3];                                      d->framebuffer + dest_ofs;
274                                  if (d->bit_depth == 24)  
275                                          for (x=0; x<linelen; x+=3) {                                  if (d->bit_depth == 24) {
276                                            for (x=0; x<linelen && x<sizeof(buf);
277                                                x += 3) {
278                                                  buf[x] = fill_r;                                                  buf[x] = fill_r;
279                                                  buf[x+1] = fill_g;                                                  buf[x+1] = fill_g;
280                                                  buf[x+2] = fill_b;                                                  buf[x+2] = fill_b;
281                                          }                                          }
282                                  else                                  } else if (d->bit_depth == 8) {
283                                          printf("TODO: fill for non-24-bit"                                          memset(buf, fill_r, linelen);
284                                              " modes\n");                                  } else {
285                                            fatal("Unimplemented bit-depth (%i)"
286                                  memmove(d->framebuffer + dest_ofs, buf,                                              " for fb fill\n", d->bit_depth);
287                                      linelen);                                          exit(1);
288                                    }
289                          }                          }
290    
291                          dest_ofs += d->bytes_per_line;                          dest_ofs += d->bytes_per_line;
# Line 266  void framebuffer_blockcopyfill(struct vf Line 293  void framebuffer_blockcopyfill(struct vf
293          } else {          } else {
294                  from_ofs = d->bytes_per_line * from_y +                  from_ofs = d->bytes_per_line * from_y +
295                      (d->bit_depth/8) * from_x;                      (d->bit_depth/8) * from_x;
   
296                  for (y=y1; y<=y2; y++) {                  for (y=y1; y<=y2; y++) {
297                          if (y>=0 && y<d->ysize)                          if (y >= 0 && y < d->ysize) {
298                                  memmove(d->framebuffer + dest_ofs,                                  if (from_y >= 0 && from_y < d->ysize)
299                                      d->framebuffer + from_ofs, linelen);                                          memmove(d->framebuffer + dest_ofs,
300                                                d->framebuffer + from_ofs, linelen);
301                                    else
302                                            memset(d->framebuffer + dest_ofs,
303                                                0, linelen);
304                            }
305                            from_y ++;
306                          from_ofs += d->bytes_per_line;                          from_ofs += d->bytes_per_line;
307                          dest_ofs += d->bytes_per_line;                          dest_ofs += d->bytes_per_line;
308                  }                  }
# Line 290  void framebuffer_blockcopyfill(struct vf Line 321  void framebuffer_blockcopyfill(struct vf
321    
322    
323  #ifdef WITH_X11  #ifdef WITH_X11
 #define macro_put_pixel() {     \  
         /*  Combine the color into an X11 long and display it:  */      \  
         /*  TODO:  construct color in a more portable way:  */          \  
         switch (d->fb_window->x11_screen_depth) {                       \  
         case 24:                                                        \  
                 if (d->fb_window->fb_ximage->byte_order)                \  
                         color = (b << 16) + (g << 8) + r;               \  
                 else                                                    \  
                         color = (r << 16) + (g << 8) + b;               \  
                 break;                                                  \  
         case 16:                                                        \  
                 r >>= 3; g >>= 2; b >>= 3;                              \  
                 if (d->fb_window->fb_ximage->byte_order) {              \  
                         /*  Big endian 16-bit X server:  */             \  
                         static int first = 1;                           \  
                         if (first) {                                    \  
                                 fprintf(stderr, "\n*** Please report "  \  
                                     "to the author whether 16-bit X11 " \  
                                     "colors are rendered correctly or " \  
                                     "not!\n\n");                        \  
                                 first = 0;                              \  
                         }                                               \  
                         color = (b << 11) + (g << 5) + r;               \  
                 } else {                                                \  
                         /*  Little endian (eg PC) X servers:  */        \  
                         color = (r << 11) + (g << 5) + b;               \  
                 }                                                       \  
                 break;                                                  \  
         case 15:                                                        \  
                 r >>= 3; g >>= 3; b >>= 3;                              \  
                 if (d->fb_window->fb_ximage->byte_order) {              \  
                         /*  Big endian 15-bit X server:  */             \  
                         static int first = 1;                           \  
                         if (first) {                                    \  
                                 fprintf(stderr, "\n*** Please report "  \  
                                     "to the author whether 15-bit X11 " \  
                                     "colors are rendered correctly or " \  
                                     "not!\n\n");                        \  
                                 first = 0;                              \  
                         }                                               \  
                         color = (b << 10) + (g << 5) + r;               \  
                 } else {                                                \  
                         /*  Little endian (eg PC) X servers:  */        \  
                         color = (r << 10) + (g << 5) + b;               \  
                 }                                                       \  
                 break;                                                  \  
         default:                                                        \  
                 color = d->fb_window->x11_graycolor[15 * (r + g + b)    \  
                     / (255 * 3)].pixel;                                 \  
         }                                                               \  
         if (x>=0 && x<d->x11_xsize && y>=0 && y<d->x11_ysize)           \  
                 XPutPixel(d->fb_window->fb_ximage, x, y, color);        \  
     }  
 #else  
 /*  If not WITH_X11:  */  
 #define macro_put_pixel() { }  
 #endif  
   
   
 /*  
  *  update_framebuffer():  
  *  
  *  The framebuffer memory has been updated. This function tries to make  
  *  sure that the XImage is also updated (1 or more pixels).  
  */  
 void update_framebuffer(struct vfb_data *d, int addr, int len)  
 {  
         int x, y, pixel, npixels;  
         long color_r, color_g, color_b;  
 #ifdef WITH_X11  
         long color;  
 #endif  
         int scaledown = d->vfb_scaledown;  
         int scaledownXscaledown = 1;  
   
         if (scaledown == 1) {  
                 /*  Which framebuffer pixel does addr correspond to?  */  
                 pixel = addr * 8 / d->bit_depth;  
                 y = pixel / d->xsize;  
                 x = pixel % d->xsize;  
   
                 /*  How many framebuffer pixels?  */  
                 npixels = len * 8 / d->bit_depth;  
                 if (npixels == 0)  
                         npixels = 1;  
   
                 if (d->bit_depth < 8) {  
                         for (pixel=0; pixel<npixels; pixel++) {  
                                 int fb_addr, c, r, g, b;  
                                 color_r = color_g = color_b = 0;  
   
                                 fb_addr = (y * d->xsize + x) * d->bit_depth;  
                                 /*  fb_addr is now which _bit_ in  
                                     the framebuffer  */  
   
                                 c = d->framebuffer[fb_addr >> 3];  
                                 fb_addr &= 7;  
   
                                 /*  HPCmips is reverse:  */  
                                 if (d->vfb_type == VFB_HPCMIPS)  
                                         fb_addr = 8 - d->bit_depth - fb_addr;  
   
                                 c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);  
                                 /*  c <<= (8 - d->bit_depth);  */  
   
                                 r = d->rgb_palette[c*3 + 0];  
                                 g = d->rgb_palette[c*3 + 1];  
                                 b = d->rgb_palette[c*3 + 2];  
   
                                 macro_put_pixel();  
                                 x++;  
                         }  
                 } else if (d->bit_depth == 8) {  
                         for (pixel=0; pixel<npixels; pixel++) {  
                                 int fb_addr, c, r, g, b;  
                                 color_r = color_g = color_b = 0;  
   
                                 fb_addr = y * d->xsize + x;  
                                 /*  fb_addr is now which byte in framebuffer  */  
                                 c = d->framebuffer[fb_addr];  
                                 r = d->rgb_palette[c*3 + 0];  
                                 g = d->rgb_palette[c*3 + 1];  
                                 b = d->rgb_palette[c*3 + 2];  
324    
325                                  macro_put_pixel();  #define REDRAW  redraw_fallback
326                                  x++;  #include "fb_include.c"
327                          }  #undef REDRAW
328                  } else {        /*  d->bit_depth > 8  */  
329                          for (pixel=0; pixel<npixels; pixel++) {  #define FB_24
330                                  int fb_addr, r, g, b;  #define REDRAW  redraw_24
331                                  color_r = color_g = color_b = 0;  #include "fb_include.c"
332    #undef REDRAW
333                                  fb_addr = (y * d->xsize + x) * d->bit_depth;  #undef FB_24
334                                  /*  fb_addr is now which byte in framebuffer  */  #define FB_16
335    #define REDRAW  redraw_16
336                                  /*  > 8 bits color.  */  #include "fb_include.c"
337                                  fb_addr >>= 3;  #undef FB_16
338                                  switch (d->bit_depth) {  #undef REDRAW
339                                  case 24:  #define FB_15
340                                          r = d->framebuffer[fb_addr];  #define REDRAW  redraw_15
341                                          g = d->framebuffer[fb_addr + 1];  #include "fb_include.c"
342                                          b = d->framebuffer[fb_addr + 2];  #undef REDRAW
343                                          break;  #undef FB_15
344                                  /*  TODO: copy to the scaledown code below  */  
345                                  case 16:  #define FB_BO
346                                          if (d->vfb_type == VFB_HPCMIPS) {  #define FB_24
347                                                  b = d->framebuffer[fb_addr] +  #define REDRAW  redraw_24_bo
348                                                      (d->framebuffer[fb_addr+1]  #include "fb_include.c"
349                                                      << 8);  #undef REDRAW
350    #undef FB_24
351                                                  if (d->color32k) {  #define FB_16
352                                                          r = b >> 11;  #define REDRAW  redraw_16_bo
353                                                          g = b >> 5;  #include "fb_include.c"
354                                                          r = r & 31;  #undef FB_16
355                                                          g = (g & 31) * 2;  #undef REDRAW
356                                                          b = b & 31;  #define FB_15
357                                                  } else if (d->psp_15bit) {  #define REDRAW  redraw_15_bo
358                                                          int tmp;  #include "fb_include.c"
359                                                          r = (b >> 10) & 0x1f;  #undef REDRAW
360                                                          g = (b >>  5) & 0x1f;  #undef FB_15
361                                                          b = b & 0x1f;  #undef FB_BO
362                                                          g <<= 1;  
363                                                          tmp = r; r = b; b = tmp;  #define FB_SCALEDOWN
364                                                  } else {  
365                                                          r = (b >> 11) & 0x1f;  #define REDRAW  redraw_fallback_sd
366                                                          g = (b >>  5) & 0x3f;  #include "fb_include.c"
367                                                          b = b & 0x1f;  #undef REDRAW
368                                                  }  
369                                          } else {  #define FB_24
370                                              r = d->framebuffer[fb_addr] >> 3;  #define REDRAW  redraw_24_sd
371                                              g = (d->framebuffer[fb_addr] << 5) +  #include "fb_include.c"
372                                                (d->framebuffer[fb_addr + 1] >>5);  #undef REDRAW
373                                              b = d->framebuffer[fb_addr + 1]&31;  #undef FB_24
374                                          }  #define FB_16
375    #define REDRAW  redraw_16_sd
376                                          r *= 8;  #include "fb_include.c"
377                                          g *= 4;  #undef FB_16
378                                          b *= 8;  #undef REDRAW
379                                          break;  #define FB_15
380                                  default:  #define REDRAW  redraw_15_sd
381                                          r = g = b = random() & 255;  #include "fb_include.c"
382                                  }  #undef REDRAW
383    #undef FB_15
384                                  macro_put_pixel();  
385                                  x++;  #define FB_BO
386                          }  #define FB_24
387                  }  #define REDRAW  redraw_24_bo_sd
388    #include "fb_include.c"
389                  return;  #undef REDRAW
390          }  #undef FB_24
391    #define FB_16
392          /*  scaledown > 1:  */  #define REDRAW  redraw_16_bo_sd
393    #include "fb_include.c"
394    #undef FB_16
395    #undef REDRAW
396    #define FB_15
397    #define REDRAW  redraw_15_bo_sd
398    #include "fb_include.c"
399    #undef REDRAW
400    #undef FB_15
401    #undef FB_BO
402    
403    void (*redraw[2 * 4 * 2])(struct vfb_data *, int, int) = {
404            redraw_fallback, redraw_fallback,
405            redraw_15, redraw_15_bo,
406            redraw_16, redraw_16_bo,
407            redraw_24, redraw_24_bo,
408            redraw_fallback_sd, redraw_fallback_sd,
409            redraw_15_sd, redraw_15_bo_sd,
410            redraw_16_sd, redraw_16_bo_sd,
411            redraw_24_sd, redraw_24_bo_sd  };
412    
413          scaledown = d->vfb_scaledown;  #endif  /*  WITH_X11  */
         scaledownXscaledown = scaledown * scaledown;  
   
         /*  Which framebuffer pixel does addr correspond to?  */  
         pixel = addr * 8 / d->bit_depth;  
         y = pixel / d->xsize;  
         x = pixel % d->xsize;  
   
         /*  How many framebuffer pixels?  */  
         npixels = len * 8 / d->bit_depth;  
   
         /*  Which x11 pixel?  */  
         x /= scaledown;  
         y /= scaledown;  
   
         /*  How many x11 pixels:  */  
         npixels /= scaledown;  
         if (npixels == 0)  
                 npixels = 1;  
   
         if (d->bit_depth < 8) {  
                 for (pixel=0; pixel<npixels; pixel++) {  
                         int subx, suby, r, g, b;  
                         color_r = color_g = color_b = 0;  
                         for (suby=0; suby<scaledown; suby++)  
                             for (subx=0; subx<scaledown; subx++) {  
                                 int fb_x, fb_y, fb_addr, c;  
   
                                 fb_x = x * scaledown + subx;  
                                 fb_y = y * scaledown + suby;  
                                 fb_addr = fb_y * d->xsize + fb_x;  
                                 fb_addr = fb_addr * d->bit_depth;  
                                 /*  fb_addr is now which _bit_ in  
                                     the framebuffer  */  
   
                                 c = d->framebuffer[fb_addr >> 3];  
                                 fb_addr &= 7;  
   
                                 /*  HPCmips is reverse:  */  
                                 if (d->vfb_type == VFB_HPCMIPS)  
                                         fb_addr = 8 - d->bit_depth - fb_addr;  
   
                                 c = (c >> fb_addr) & ((1<<d->bit_depth) - 1);  
                                 /*  c <<= (8 - d->bit_depth);  */  
   
                                 r = d->rgb_palette[c*3 + 0];  
                                 g = d->rgb_palette[c*3 + 1];  
                                 b = d->rgb_palette[c*3 + 2];  
   
                                 color_r += r;  
                                 color_g += g;  
                                 color_b += b;  
                             }  
   
                         r = color_r / scaledownXscaledown;  
                         g = color_g / scaledownXscaledown;  
                         b = color_b / scaledownXscaledown;  
                         macro_put_pixel();  
                         x++;  
                 }  
         } else if (d->bit_depth == 8) {  
                 for (pixel=0; pixel<npixels; pixel++) {  
                         int subx, suby, r, g, b;  
                         color_r = color_g = color_b = 0;  
                         for (suby=0; suby<scaledown; suby++)  
                             for (subx=0; subx<scaledown; subx++) {  
                                 int fb_x, fb_y, fb_addr, c;  
   
                                 fb_x = x * scaledown + subx;  
                                 fb_y = y * scaledown + suby;  
                                 fb_addr = fb_y * d->xsize + fb_x;  
                                 /*  fb_addr is which _byte_ in framebuffer  */  
                                 c = d->framebuffer[fb_addr] * 3;  
                                 r = d->rgb_palette[c + 0];  
                                 g = d->rgb_palette[c + 1];  
                                 b = d->rgb_palette[c + 2];  
                                 color_r += r;  
                                 color_g += g;  
                                 color_b += b;  
                             }  
   
                         r = color_r / scaledownXscaledown;  
                         g = color_g / scaledownXscaledown;  
                         b = color_b / scaledownXscaledown;  
                         macro_put_pixel();  
                         x++;  
                 }  
         } else {  
                 /*  Generic > 8 bit bit-depth:  */  
                 for (pixel=0; pixel<npixels; pixel++) {  
                         int subx, suby, r, g, b;  
                         color_r = color_g = color_b = 0;  
                         for (suby=0; suby<scaledown; suby++)  
                             for (subx=0; subx<scaledown; subx++) {  
                                 int fb_x, fb_y, fb_addr;  
   
                                 fb_x = x * scaledown + subx;  
                                 fb_y = y * scaledown + suby;  
                                 fb_addr = fb_y * d->xsize + fb_x;  
                                 fb_addr = (fb_addr * d->bit_depth) >> 3;  
                                 /*  fb_addr is which _byte_ in framebuffer  */  
   
                                 /*  > 8 bits color.  */  
                                 switch (d->bit_depth) {  
                                 case 24:  
                                         r = d->framebuffer[fb_addr];  
                                         g = d->framebuffer[fb_addr + 1];  
                                         b = d->framebuffer[fb_addr + 2];  
                                         break;  
                                 default:  
                                         r = g = b = random() & 255;  
                                 }  
                                 color_r += r;  
                                 color_g += g;  
                                 color_b += b;  
                             }  
                         r = color_r / scaledownXscaledown;  
                         g = color_g / scaledownXscaledown;  
                         b = color_b / scaledownXscaledown;  
                         macro_put_pixel();  
                         x++;  
                 }  
         }  
 }  
414    
415    
416  /*  /*
# Line 738  void dev_fb_tick(struct cpu *cpu, void * Line 542  void dev_fb_tick(struct cpu *cpu, void *
542  #endif  #endif
543    
544          if (d->update_x2 != -1) {          if (d->update_x2 != -1) {
545                  int y, addr, addr2, q = d->vfb_scaledown;  #ifdef WITH_X11
546                    int y;
547    #endif
548                    int addr, addr2, q = d->vfb_scaledown;
549    
550                  if (d->update_x1 >= d->visible_xsize)                  if (d->update_x1 >= d->visible_xsize)
551                          d->update_x1 = d->visible_xsize - 1;                          d->update_x1 = d->visible_xsize - 1;
# Line 763  void dev_fb_tick(struct cpu *cpu, void * Line 570  void dev_fb_tick(struct cpu *cpu, void *
570                  addr2 = d->update_y1 * d->bytes_per_line +                  addr2 = d->update_y1 * d->bytes_per_line +
571                      d->update_x2 * d->bit_depth / 8;                      d->update_x2 * d->bit_depth / 8;
572    
573    #ifdef WITH_X11
574                  for (y=d->update_y1; y<=d->update_y2; y+=q) {                  for (y=d->update_y1; y<=d->update_y2; y+=q) {
575                          update_framebuffer(d, addr, addr2 - addr);                          d->redraw_func(d, addr, addr2 - addr);
576                          addr  += d->bytes_per_line * q;                          addr  += d->bytes_per_line * q;
577                          addr2 += d->bytes_per_line * q;                          addr2 += d->bytes_per_line * q;
578                  }                  }
579    
 #ifdef WITH_X11  
580                  XPutImage(d->fb_window->x11_display, d->fb_window->                  XPutImage(d->fb_window->x11_display, d->fb_window->
581                      x11_fb_window, d->fb_window->x11_fb_gc, d->fb_window->                      x11_fb_window, d->fb_window->x11_fb_gc, d->fb_window->
582                      fb_ximage, d->update_x1/d->vfb_scaledown, d->update_y1/                      fb_ximage, d->update_x1/d->vfb_scaledown, d->update_y1/
# Line 798  void dev_fb_tick(struct cpu *cpu, void * Line 605  void dev_fb_tick(struct cpu *cpu, void *
605                              cursor_xsize;                              cursor_xsize;
606                          d->fb_window->OLD_cursor_ysize = d->fb_window->                          d->fb_window->OLD_cursor_ysize = d->fb_window->
607                              cursor_ysize;                              cursor_ysize;
608                            need_to_flush_x11 = 1;
609                  }                  }
610          }          }
611  #endif  #endif
# Line 812  void dev_fb_tick(struct cpu *cpu, void * Line 620  void dev_fb_tick(struct cpu *cpu, void *
620  /*  /*
621   *  dev_fb_access():   *  dev_fb_access():
622   */   */
623  int dev_fb_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(fb)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
624  {  {
625          struct vfb_data *d = extra;          struct vfb_data *d = extra;
626          int i;          size_t i;
627    
628  #ifdef FB_DEBUG  #ifdef FB_DEBUG
629          if (writeflag == MEM_WRITE) { if (data[0]) {          if (writeflag == MEM_WRITE) { if (data[0]) {
# Line 846  int dev_fb_access(struct cpu *cpu, struc Line 652  int dev_fb_access(struct cpu *cpu, struc
652    
653                          /*  If all bytes are equal to what is already stored                          /*  If all bytes are equal to what is already stored
654                              in the framebuffer, then simply return:  */                              in the framebuffer, then simply return:  */
655                          if (i==len-1)                          if (i == len-1)
656                                  return 1;                                  return 1;
657                  }                  }
658          }          }
# Line 905  int dev_fb_access(struct cpu *cpu, struc Line 711  int dev_fb_access(struct cpu *cpu, struc
711          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
712                  if (len > 8)                  if (len > 8)
713                          memcpy(d->framebuffer + relative_addr, data, len);                          memcpy(d->framebuffer + relative_addr, data, len);
714                  else                  else {
715                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
716                                  d->framebuffer[relative_addr + i] = data[i];                                  d->framebuffer[relative_addr + i] = data[i];
717                    }
718          } else {          } else {
719                  if (len > 8)                  if (len > 8)
720                          memcpy(data, d->framebuffer + relative_addr, len);                          memcpy(data, d->framebuffer + relative_addr, len);
721                  else                  else {
722                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
723                                  data[i] = d->framebuffer[relative_addr + i];                                  data[i] = d->framebuffer[relative_addr + i];
724                    }
725          }          }
726    
727          return 1;          return 1;
# Line 936  int dev_fb_access(struct cpu *cpu, struc Line 744  int dev_fb_access(struct cpu *cpu, struc
744   *   *
745   *  VFB_DEC_VFB01, _VFB02, and VFB_DEC_MAXINE are DECstation specific.   *  VFB_DEC_VFB01, _VFB02, and VFB_DEC_MAXINE are DECstation specific.
746   *   *
747   *  If type is VFB_HPCMIPS, then color encoding differs from the generic case.   *  If type is VFB_HPC, then color encoding differs from the generic case.
748   *   *
749   *  If bit_depth = -15 (note the minus sign), then a special hack is used for   *  If bit_depth = -15 (note the minus sign), then a special hack is used for
750   *  the Playstation Portable's 5-bit R, 5-bit G, 5-bit B.   *  the Playstation Portable's 5-bit R, 5-bit G, 5-bit B.
# Line 948  struct vfb_data *dev_fb_init(struct mach Line 756  struct vfb_data *dev_fb_init(struct mach
756          struct vfb_data *d;          struct vfb_data *d;
757          size_t size, nlen;          size_t size, nlen;
758          int flags;          int flags;
759          char title[400];          int reverse_start = 0;
760          char *name2;          char *name2;
761    
762          d = malloc(sizeof(struct vfb_data));          d = malloc(sizeof(struct vfb_data));
# Line 958  struct vfb_data *dev_fb_init(struct mach Line 766  struct vfb_data *dev_fb_init(struct mach
766          }          }
767          memset(d, 0, sizeof(struct vfb_data));          memset(d, 0, sizeof(struct vfb_data));
768    
769            if (vfb_type & VFB_REVERSE_START) {
770                    vfb_type &= ~VFB_REVERSE_START;
771                    reverse_start = 1;
772            }
773    
774            d->memory = mem;
775          d->vfb_type = vfb_type;          d->vfb_type = vfb_type;
776    
777          /*  Defaults:  */          /*  Defaults:  */
# Line 1000  struct vfb_data *dev_fb_init(struct mach Line 814  struct vfb_data *dev_fb_init(struct mach
814                  d->ysize = ysize;  d->visible_ysize = d->ysize;                  d->ysize = ysize;  d->visible_ysize = d->ysize;
815                  d->bit_depth = 24;                  d->bit_depth = 24;
816                  break;                  break;
         default:  
                 ;  
817          }          }
818    
819          if (d->bit_depth == 2 || d->bit_depth == 4)          if (d->bit_depth == 2 || d->bit_depth == 4)
# Line 1022  struct vfb_data *dev_fb_init(struct mach Line 834  struct vfb_data *dev_fb_init(struct mach
834    
835          /*  Clear the framebuffer (all black pixels):  */          /*  Clear the framebuffer (all black pixels):  */
836          d->framebuffer_size = size;          d->framebuffer_size = size;
837          memset(d->framebuffer, 0, size);          memset(d->framebuffer, reverse_start? 255 : 0, size);
838    
839          d->x11_xsize = d->visible_xsize / d->vfb_scaledown;          d->x11_xsize = d->visible_xsize / d->vfb_scaledown;
840          d->x11_ysize = d->visible_ysize / d->vfb_scaledown;          d->x11_ysize = d->visible_ysize / d->vfb_scaledown;
841    
842          d->update_x1 = d->update_y1 = 99999;          /*  Only "update" from the start if we need to fill with white.  */
843          d->update_x2 = d->update_y2 = -1;          /*  (The Ximage will be black from the start anyway.)  */
844            if (reverse_start) {
845                    d->update_x1 = d->update_y1 = 0;
846                    d->update_x2 = d->xsize - 1;
847                    d->update_y2 = d->ysize - 1;
848            } else {
849                    d->update_x1 = d->update_y1 = 99999;
850                    d->update_x2 = d->update_y2 = -1;
851            }
852    
853          /*  Don't set the title to include the size of the framebuffer for          d->name = strdup(name);
854              VGA, since then the resolution might change during runtime.  */          set_title(d);
         if (strcmp(name, "VGA") == 0)  
                 snprintf(title, sizeof(title),"GXemul: %s framebuffer", name);  
         else  
                 snprintf(title, sizeof(title),"GXemul: %ix%ix%i %s framebuffer",  
                     d->visible_xsize, d->visible_ysize, d->bit_depth, name);  
         title[sizeof(title)-1] = '\0';  
855    
856  #ifdef WITH_X11  #ifdef WITH_X11
857          if (machine->use_x11)          if (machine->use_x11) {
858                    int i = 0;
859                  d->fb_window = x11_fb_init(d->x11_xsize, d->x11_ysize,                  d->fb_window = x11_fb_init(d->x11_xsize, d->x11_ysize,
860                      title, machine->x11_scaledown, machine);                      d->title, machine->x11_scaledown, machine);
861          else                  switch (d->fb_window->x11_screen_depth) {
862                    case 15: i = 2; break;
863                    case 16: i = 4; break;
864                    case 24: i = 6; break;
865                    }
866                    if (d->fb_window->fb_ximage->byte_order)
867                            i ++;
868                    if (d->vfb_scaledown > 1)
869                            i += 8;
870                    d->redraw_func = redraw[i];
871            } else
872  #endif  #endif
873                  d->fb_window = NULL;                  d->fb_window = NULL;
874    
# Line 1056  struct vfb_data *dev_fb_init(struct mach Line 880  struct vfb_data *dev_fb_init(struct mach
880          }          }
881          snprintf(name2, nlen, "fb [%s]", name);          snprintf(name2, nlen, "fb [%s]", name);
882    
883          flags = MEM_DEFAULT;          flags = DM_DEFAULT;
884          if ((baseaddr & 0xfff) == 0)          if ((baseaddr & 0xfff) == 0)
885                  flags = MEM_DYNTRANS_OK | MEM_DYNTRANS_WRITE_OK;                  flags = DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK;
886    
887          flags |= MEM_READING_HAS_NO_SIDE_EFFECTS;          flags |= DM_READS_HAVE_NO_SIDE_EFFECTS;
888    
889          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,
890              d, flags, d->framebuffer);              d, flags, d->framebuffer);
891    
892          machine_add_tickfunction(machine, dev_fb_tick, d, FB_TICK_SHIFT);          machine_add_tickfunction(machine, dev_fb_tick, d, FB_TICK_SHIFT, 0.0);
893          return d;          return d;
894  }  }
895    

Legend:
Removed from v.14  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26