/[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 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_fb.c,v 1.90 2005/03/29 09:46:06 debug Exp $   *  $Id: dev_fb.c,v 1.106 2005/08/14 11:14:38 debug Exp $
29   *     *  
30   *  Generic framebuffer device.   *  Generic framebuffer device.
31   *   *
# Line 65  Line 65 
65  #endif  #endif
66    
67    
68  #define FB_TICK_SHIFT           18  #define FB_TICK_SHIFT           19
   
 #define LOGO_XSIZE              256  
 #define LOGO_YSIZE              256  
 #define LOGO_BOTTOM_MARGIN      60  
 /*  This must be a 256*256 pixels P4 ppm:  */  
 #include "fb_logo.c"  
 unsigned char *fb_logo = fb_logo_ppm + 11;  
69    
70    
71  /*  #define FB_DEBUG  */  /*  #define FB_DEBUG  */
# Line 115  void set_blackwhite_palette(struct vfb_d Line 108  void set_blackwhite_palette(struct vfb_d
108    
109    
110  /*  /*
111     *  dev_fb_resize():
112     *
113     *  Resize a framebuffer window. (This functionality is probably a bit buggy,
114     *  because I didn't think of including it from the start.)
115     */
116    void dev_fb_resize(struct vfb_data *d, int new_xsize, int new_ysize)
117    {
118            unsigned char *new_framebuffer;
119            int y, new_bytes_per_line;
120            size_t size;
121    
122            if (d == NULL) {
123                    fatal("dev_fb_resize(): d == NULL\n");
124                    return;
125            }
126    
127            new_bytes_per_line = new_xsize * d->bit_depth / 8;
128            size = new_ysize * new_bytes_per_line;
129    
130            new_framebuffer = malloc(size);
131            if (new_framebuffer == NULL) {
132                    fprintf(stderr, "dev_fb_resize(): out of memory\n");
133                    exit(1);
134            }
135    
136            /*  Copy the old framebuffer to the new:  */
137            if (d->framebuffer != NULL) {
138                    for (y=0; y<new_ysize; y++) {
139                            size_t fromofs = d->bytes_per_line * y;
140                            size_t toofs = new_bytes_per_line * y;
141                            size_t len_to_copy = d->bytes_per_line <
142                                new_bytes_per_line? d->bytes_per_line      
143                                : new_bytes_per_line;
144                            memset(new_framebuffer + toofs, 0, new_bytes_per_line);
145                            if (y < d->x11_ysize)
146                                    memmove(new_framebuffer + toofs,
147                                        d->framebuffer + fromofs, len_to_copy);
148                    }
149    
150                    free(d->framebuffer);
151            }
152    
153            d->framebuffer = new_framebuffer;
154            d->framebuffer_size = size;
155    
156            if (new_xsize > d->x11_xsize || new_ysize > d->x11_ysize) {
157                    d->update_x1 = d->update_y1 = 0;
158                    d->update_x2 = new_xsize - 1;
159                    d->update_y2 = new_ysize - 1;
160            }
161    
162            d->bytes_per_line = new_bytes_per_line;
163            d->x11_xsize = d->visible_xsize = new_xsize;
164            d->x11_ysize = d->visible_ysize = new_ysize;
165    
166    #ifdef WITH_X11
167            if (d->fb_window != NULL)
168                    x11_fb_resize(d->fb_window, new_xsize, new_ysize);
169    #endif
170    }
171    
172    
173    /*
174   *  dev_fb_setcursor():   *  dev_fb_setcursor():
175   */   */
176  void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on,  void dev_fb_setcursor(struct vfb_data *d, int cursor_x, int cursor_y, int on,
# Line 382  void update_framebuffer(struct vfb_data Line 438  void update_framebuffer(struct vfb_data
438                                                          r = r & 31;                                                          r = r & 31;
439                                                          g = (g & 31) * 2;                                                          g = (g & 31) * 2;
440                                                          b = b & 31;                                                          b = b & 31;
441                                                    } else if (d->psp_15bit) {
442                                                            int tmp;
443                                                            r = (b >> 10) & 0x1f;
444                                                            g = (b >>  5) & 0x1f;
445                                                            b = b & 0x1f;
446                                                            g <<= 1;
447                                                            tmp = r; r = b; b = tmp;
448                                                  } else {                                                  } else {
449                                                          r = (b >> 11) & 0x1f;                                                          r = (b >> 11) & 0x1f;
450                                                          g = (b >>  5) & 0x3f;                                                          g = (b >>  5) & 0x3f;
# Line 410  void update_framebuffer(struct vfb_data Line 473  void update_framebuffer(struct vfb_data
473                  return;                  return;
474          }          }
475    
476          /*  scaledown != 1:  */          /*  scaledown > 1:  */
477    
478          scaledown = d->vfb_scaledown;          scaledown = d->vfb_scaledown;
479          scaledownXscaledown = scaledown * scaledown;          scaledownXscaledown = scaledown * scaledown;
# Line 553  void dev_fb_tick(struct cpu *cpu, void * Line 616  void dev_fb_tick(struct cpu *cpu, void *
616          if (!cpu->machine->use_x11)          if (!cpu->machine->use_x11)
617                  return;                  return;
618    
 #ifdef BINTRANS  
619          do {          do {
620                  uint64_t low = -1, high;                  uint64_t high, low = (uint64_t)(int64_t) -1;
621                  int x, y;                  int x, y;
622    
623                  memory_device_bintrans_access(cpu, cpu->mem,                  memory_device_dyntrans_access(cpu, cpu->mem,
624                      extra, &low, &high);                      extra, &low, &high);
625                  if ((int64_t)low == -1)                  if ((int64_t)low == -1)
626                          break;                          break;
# Line 619  void dev_fb_tick(struct cpu *cpu, void * Line 681  void dev_fb_tick(struct cpu *cpu, void *
681                          d->update_x2 = d->xsize-1;                          d->update_x2 = d->xsize-1;
682                  }                  }
683          } while (0);          } while (0);
 #endif  
684    
685  #ifdef WITH_X11  #ifdef WITH_X11
686          /*  Do we need to redraw the cursor?  */          /*  Do we need to redraw the cursor?  */
# Line 750  int dev_fb_access(struct cpu *cpu, struc Line 811  int dev_fb_access(struct cpu *cpu, struc
811          }          }
812  #endif  #endif
813    
814            if (relative_addr >= d->framebuffer_size)
815                    return 0;
816    
817          /*  See if a write actually modifies the framebuffer contents:  */          /*  See if a write actually modifies the framebuffer contents:  */
818          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
819                  for (i=0; i<len; i++) {                  for (i=0; i<len; i++) {
# Line 835  int dev_fb_access(struct cpu *cpu, struc Line 899  int dev_fb_access(struct cpu *cpu, struc
899  /*  /*
900   *  dev_fb_init():   *  dev_fb_init():
901   *   *
902   *  xsize and ysize are ignored if vfb_type is VFB_DEC_VFB01 or 02.   *  This function is big and ugly, but the point is to initialize a framebuffer
903     *  device. :-)
904     *
905     *  visible_xsize and visible_ysize are the sizes of the visible display area.
906     *  xsize and ysize tell how much memory is actually allocated (for example
907     *  visible_xsize could be 640, but xsize could be 1024, for better alignment).
908     *
909     *  vfb_type is useful for selecting special features.
910     *
911     *  type = VFB_GENERIC is the most useful type, especially when bit_depth = 24.
912     *
913     *  VFB_DEC_VFB01, _VFB02, and VFB_DEC_MAXINE are DECstation specific.
914     *
915     *  If type is VFB_HPCMIPS, then color encoding differs from the generic case.
916     *
917     *  If bit_depth = -15 (note the minus sign), then a special hack is used for
918     *  the Playstation Portable's 5-bit R, 5-bit G, 5-bit B.
919   */   */
920  struct vfb_data *dev_fb_init(struct machine *machine, struct memory *mem,  struct vfb_data *dev_fb_init(struct machine *machine, struct memory *mem,
921          uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize,          uint64_t baseaddr, int vfb_type, int visible_xsize, int visible_ysize,
922          int xsize, int ysize, int bit_depth, char *name, int logo)          int xsize, int ysize, int bit_depth, char *name)
923  {  {
924          struct vfb_data *d;          struct vfb_data *d;
925          size_t size;          size_t size, nlen;
926          int x, y;          int flags;
927          char title[400];          char title[400];
928          char *name2;          char *name2;
         int flags;  
929    
930          d = malloc(sizeof(struct vfb_data));          d = malloc(sizeof(struct vfb_data));
931          if (d == NULL) {          if (d == NULL) {
# Line 866  struct vfb_data *dev_fb_init(struct mach Line 945  struct vfb_data *dev_fb_init(struct mach
945          if (bit_depth == 15) {          if (bit_depth == 15) {
946                  d->color32k = 1;                  d->color32k = 1;
947                  bit_depth = d->bit_depth = 16;                  bit_depth = d->bit_depth = 16;
948            } else if (bit_depth == -15) {
949                    d->psp_15bit = 1;
950                    bit_depth = d->bit_depth = 16;
951          }          }
952    
953          /*  Specific types:  */          /*  Specific types:  */
# Line 925  struct vfb_data *dev_fb_init(struct mach Line 1007  struct vfb_data *dev_fb_init(struct mach
1007          d->update_x2 = d->update_y2 = -1;          d->update_x2 = d->update_y2 = -1;
1008    
1009    
1010          /*  A nice bootup logo:  */          /*  Don't set the title to include the size of the framebuffer for
1011          if (logo) {              VGA, since then the resolution might change during runtime.  */
1012                  int logo_bottom_margin = LOGO_BOTTOM_MARGIN;          if (strcmp(name, "VGA") == 0)
1013                    snprintf(title, sizeof(title),"GXemul: %s framebuffer", name);
1014                  d->update_x1 = 0;          else
1015                  d->update_x2 = LOGO_XSIZE-1;                  snprintf(title, sizeof(title),"GXemul: %ix%ix%i %s framebuffer",
1016                  d->update_y1 = d->visible_ysize-LOGO_YSIZE-logo_bottom_margin;                      d->visible_xsize, d->visible_ysize, d->bit_depth, name);
                 d->update_y2 = d->visible_ysize-logo_bottom_margin;  
                 for (y=0; y<LOGO_YSIZE; y++)  
                         for (x=0; x<LOGO_XSIZE; x++) {  
                                 int s, a = ((y + d->visible_ysize - LOGO_YSIZE  
                                     - logo_bottom_margin)*d->xsize + x)  
                                     * d->bit_depth / 8;  
                                 int b = fb_logo[(y*LOGO_XSIZE+x) / 8] &  
                                     (128 >> (x&7));  
                                 for (s=0; s<d->bit_depth / 8; s++)  
                                         d->framebuffer[a+s] = b? 0 : 255;  
                         }  
         }  
   
         snprintf(title, sizeof(title), "GXemul: %ix%ix%i %s framebuffer",  
             d->visible_xsize, d->visible_ysize, d->bit_depth, name);  
1017          title[sizeof(title)-1] = '\0';          title[sizeof(title)-1] = '\0';
1018    
1019  #ifdef WITH_X11  #ifdef WITH_X11
# Line 957  struct vfb_data *dev_fb_init(struct mach Line 1024  struct vfb_data *dev_fb_init(struct mach
1024  #endif  #endif
1025                  d->fb_window = NULL;                  d->fb_window = NULL;
1026    
1027          name2 = malloc(strlen(name) + 10);          nlen = strlen(name) + 10;
1028            name2 = malloc(nlen);
1029          if (name2 == NULL) {          if (name2 == NULL) {
1030                  fprintf(stderr, "out of memory in dev_fb_init()\n");                  fprintf(stderr, "out of memory in dev_fb_init()\n");
1031                  exit(1);                  exit(1);
1032          }          }
1033          sprintf(name2, "fb [%s]", name);          snprintf(name2, nlen, "fb [%s]", name);
1034    
1035          flags = MEM_DEFAULT;          flags = MEM_DEFAULT;
1036          if ((baseaddr & 0xfff) == 0)          if ((baseaddr & 0xfff) == 0)
1037                  flags = MEM_BINTRANS_OK | MEM_BINTRANS_WRITE_OK;                  flags = MEM_DYNTRANS_OK | MEM_DYNTRANS_WRITE_OK;
1038    
1039            flags |= MEM_READING_HAS_NO_SIDE_EFFECTS;
1040    
1041          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,          memory_device_register(mem, name2, baseaddr, size, dev_fb_access,
1042              d, flags, d->framebuffer);              d, flags, d->framebuffer);

Legend:
Removed from v.4  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26