#include <memory.h>
#include <linux/kd.h>
-#include <lib/base/econfig.h>
#include <lib/gdi/fb.h>
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#endif
+
+#ifndef FBIO_BLIT
+#define FBIO_SET_MANUAL_BLIT _IOW('F', 0x21, __u8)
+#define FBIO_BLIT 0x22
+#endif
+
fbClass *fbClass::instance;
fbClass *fbClass::getInstance()
fbClass::fbClass(const char *fb)
{
+ m_manual_blit=-1;
instance=this;
locked=0;
available=0;
perror(fb);
goto nolfb;
}
+
+
if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0)
{
perror("FBIOGET_VSCREENINFO");
}
available=fix.smem_len;
+ m_phys_mem = fix.smem_start;
eDebug("%dk video mem", available/1024);
lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
if (!lfb)
goto nolfb;
}
-// showConsole(0);
+ showConsole(0);
+
+ enableManualBlit();
return;
nolfb:
lfb=0;
int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp)
{
screeninfo.xres_virtual=screeninfo.xres=nxRes;
- screeninfo.yres_virtual=screeninfo.yres=nyRes;
+ screeninfo.yres_virtual=(screeninfo.yres=nyRes)*2;
screeninfo.height=0;
screeninfo.width=0;
screeninfo.xoffset=screeninfo.yoffset=0;
screeninfo.bits_per_pixel=nbpp;
+
+ switch (nbpp) {
+ case 16:
+ // ARGB 1555
+ screeninfo.transp.offset = 15;
+ screeninfo.transp.length = 1;
+ screeninfo.red.offset = 10;
+ screeninfo.red.length = 5;
+ screeninfo.green.offset = 5;
+ screeninfo.green.length = 5;
+ screeninfo.blue.offset = 0;
+ screeninfo.blue.length = 5;
+ break;
+ case 32:
+ // ARGB 8888
+ screeninfo.transp.offset = 24;
+ screeninfo.transp.length = 8;
+ screeninfo.red.offset = 16;
+ screeninfo.red.length = 8;
+ screeninfo.green.offset = 8;
+ screeninfo.green.length = 8;
+ screeninfo.blue.offset = 0;
+ screeninfo.blue.length = 8;
+ break;
+ }
+
if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
{
- perror("FBIOPUT_VSCREENINFO");
- printf("fb failed\n");
- return -1;
- }
+ // try single buffering
+ screeninfo.yres_virtual=screeninfo.yres=nyRes;
+
+ if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
+ {
+ perror("FBIOPUT_VSCREENINFO");
+ printf("fb failed\n");
+ return -1;
+ }
+ eDebug(" - double buffering not available.");
+ } else
+ eDebug(" - double buffering available!");
+
+ m_number_of_pages = screeninfo.yres_virtual / nyRes;
+
+ ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo);
+
if ((screeninfo.xres!=nxRes) && (screeninfo.yres!=nyRes) && (screeninfo.bits_per_pixel!=nbpp))
{
eDebug("SetMode failed: wanted: %dx%dx%d, got %dx%dx%d",
return 0;
}
-fbClass::~fbClass()
+int fbClass::setOffset(int off)
{
- if (available)
- ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen);
- if (lfb)
- munmap(lfb, available);
- showConsole(1);
+ screeninfo.xoffset = 0;
+ screeninfo.yoffset = off;
+ return ioctl(fd, FBIOPAN_DISPLAY, &screeninfo);
}
-int fbClass::PutCMAP()
+int fbClass::waitVSync()
{
- return ioctl(fd, FBIOPUTCMAP, &cmap);
+ int c = 0;
+ return ioctl(fd, FBIO_WAITFORVSYNC, &c);
}
-void fbClass::Box(int x, int y, int width, int height, int color, int backcolor)
+void fbClass::blit()
{
- if (width<=2 || locked)
- return;
- int offset=y*stride+x/2;
- int first=0xF0|((color&0xF0)>>4);
- int last= 0xF0|((backcolor&0xF0)>>4);
- color=(color&0xF)*0x11;
- int halfwidth=width/2;
- for (int ay=y; ay<(y+height); ay++)
- {
- lfb[offset]=first;
- memset(lfb+offset+1, color, halfwidth-2);
- lfb[offset+halfwidth-1]=last;
- offset+=stride;
+ if (m_manual_blit == 1) {
+ if (ioctl(fd, FBIO_BLIT) < 0)
+ perror("FBIO_BLIT");
}
}
-void fbClass::NBox(int x, int y, int width, int height, int color)
+fbClass::~fbClass()
{
- if (locked)
- return;
- int offset=y*stride+x/2;
- int halfwidth=width/2;
- for (int ay=y; ay<(y+height); ay++)
- {
- memset(lfb+offset, color, halfwidth);
- offset+=stride;
- }
+ if (available)
+ ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen);
+ if (lfb)
+ munmap(lfb, available);
+ showConsole(1);
+ disableManualBlit();
}
-void fbClass::VLine(int x, int y, int sy, int color)
+int fbClass::PutCMAP()
{
- if (locked)
- return;
- int offset=y*stride+x/2;
- while (sy--)
- {
- lfb[offset]=color;
- offset+=stride;
- }
+ return ioctl(fd, FBIOPUTCMAP, &cmap);
}
int fbClass::lock()
{
if (locked)
return -1;
- locked=1;
+ if (m_manual_blit == 1)
+ {
+ locked = 2;
+ disableManualBlit();
+ }
+ else
+ locked = 1;
return fd;
}
{
if (!locked)
return;
+ if (locked == 2) // re-enable manualBlit
+ enableManualBlit();
locked=0;
SetMode(xRes, yRes, bpp);
PutCMAP();
}
+
+void fbClass::enableManualBlit()
+{
+ unsigned char tmp = 1;
+ if (ioctl(fd,FBIO_SET_MANUAL_BLIT, &tmp)<0)
+ perror("FBIO_SET_MANUAL_BLIT");
+ else
+ m_manual_blit = 1;
+}
+
+void fbClass::disableManualBlit()
+{
+ unsigned char tmp = 0;
+ if (ioctl(fd,FBIO_SET_MANUAL_BLIT, &tmp)<0)
+ perror("FBIO_SET_MANUAL_BLIT");
+ else
+ m_manual_blit = 0;
+}
+