掌機 - Pandora(Rebirth) - SuperZaxxon - C/C++ - Framebuffer



main.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <linux/omapfb.h>
#include <sys/time.h>

#define W 800
#define H 480 
#define FB_MAP_SIZE (W * H * 4 * 2)
 
static int fd = -1;
static void *pixels = NULL;

static int pre_fb(void)
{
    struct omapfb_mem_info mi = { 0 };
    struct omapfb_plane_info pi = { 0 };
    struct fb_var_screeninfo vinfo = { 0 };
    struct fb_fix_screeninfo finfo = { 0 };

    fd = open("/dev/fb1", O_RDWR);

    ioctl(fd, OMAPFB_QUERY_MEM, &mi);
    ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
    ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
 
    pi.enabled = 0;
    ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
 
    mi.size = FB_MAP_SIZE;
    ioctl(fd, OMAPFB_SETUP_MEM, &mi);
 
    pi.enabled = 1;
    pi.pos_x = 0;
    pi.pos_y = 0;
    pi.out_width = W;
    pi.out_height = H;
    ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
 
    vinfo.xoffset = 0;
    vinfo.yoffset = 0;  
    vinfo.xres = W;
    vinfo.yres = H;
    vinfo.xres_virtual = W;
    vinfo.yres_virtual = H * 2;
    ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo);

    close(fd);

    return 0; 
}
 
static int init_fb(void)
{
    struct omapfb_mem_info mi = { 0 };
    struct omapfb_plane_info pi = { 0 };
    struct fb_var_screeninfo vinfo = { 0 };
    struct fb_fix_screeninfo finfo = { 0 };

    fd = open("/dev/fb1", O_RDWR);

    ioctl(fd, OMAPFB_QUERY_MEM, &mi);
    ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
    ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
 
    pi.enabled = 0;
    ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
 
    mi.size = FB_MAP_SIZE;
    ioctl(fd, OMAPFB_SETUP_MEM, &mi);
 
    pi.enabled = 1;
    pi.pos_x = 0;
    pi.pos_y = 0;
    pi.out_width = W;
    pi.out_height = H;
    ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
 
    pixels = mmap(0, FB_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);

    vinfo.xoffset = 0;
    vinfo.yoffset = 0;  
    vinfo.xres = W;
    vinfo.yres = H;
    vinfo.xres_virtual = W;
    vinfo.yres_virtual = H * 2;
    ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo);

    return 0; 
}
 
static void deinit_fb(void)
{
    struct omapfb_mem_info mi = { 0 };
    struct omapfb_plane_info pi = { 0 };
 
    ioctl(fd, OMAPFB_QUERY_MEM, &mi);
    ioctl(fd, OMAPFB_QUERY_PLANE, &pi);

    pi.enabled = 0;
    ioctl(fd, OMAPFB_SETUP_PLANE, &pi);

    munmap(pixels, mi.size);

    mi.size = 0;
    ioctl(fd, OMAPFB_SETUP_MEM, &mi);
 
    close(fd);
}
 
int main(int argc, char *args[])
{
    int x = 0;
    int y = 0;
    int r = 0;
    int off = 0;
    int cnt = 600;
    uint32_t *p = NULL;
    uint32_t col[] = { 0xff0000, 0xff00, 0xff };
    struct fb_var_screeninfo vinfo = { 0 };

    pre_fb(); 
    init_fb();
    ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);

    while (cnt--) {
        p = (uint32_t *)pixels + (W * H * (cnt % 2)); 
        for (y = 0; y < H; y++) {
            for (x = 0; x < W; x++) {
                *p++ = col[cnt % 3];
            }
        }
        vinfo.yoffset = H * (cnt % 2);
        ioctl(fd, FBIOPAN_DISPLAY, &vinfo);
        ioctl(fd, FBIO_WAITFORVSYNC, &r);
    }
    deinit_fb();
    return 0;
}