Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <fcntl.h>
- #include <linux/fb.h>
- #include <linux/kd.h>
- #include <sys/mman.h>
- #include <errno.h>
- #include <wiringPi.h>
- #include <wiringSerial.h>
- //------------------
- #include <stdbool.h>
- #include <termio.h>
- #include "key.h"
- static int stdin_fd = -1;
- static struct termios original;
- //------------------
- int fd;
- int paletteSelected = 0;
- unsigned long paletteArray[11][4] = { // {4294967295u, 0},{0, 4294967295u}
- {0xE7DAE7DA, 0x8E0E8E0E, 0x334B334B, 0x08C408C4} // 1 BGB (lcd green)
- ,{0xEF5DEF5D, 0xA514A514, 0x5ACB5ACB, 0x10821082} // 2 grey
- ,{0xEFF9EFF9, 0xAEB2AEB2, 0x546E546E, 0x11671167} // 3 BGB 0.3
- ,{0xFF11FF11, 0xDD8BDD8B, 0x9BC79BC7, 0x49C349C3} // 4 no$gmb (brown)
- ,{0x05B005B0, 0x04CE04CE, 0x03490349, 0x02870287} // 5 gameboy light
- ,{0xEF76EF76, 0xBDE3BDE3, 0x6B606B60, 0x11C011C0} // 6 gameboy kiosk
- ,{0x568A568A, 0x45084508, 0x33863386, 0x22042204} // 7 KiGB (green)
- ,{0xFF8FFF8F, 0xB549B549, 0x6B466B46, 0x21022102} // 8 yellow
- ,{0xFE18FE18, 0xFB0CFB0C, 0xC000C000, 0x60006000} // 9 red
- ,{0xC61FC61F, 0x631F631F, 0x00180018, 0x000C000C} // 0 blue
- ,{0xFFFFFFFF, 0xB596B596, 0x6B4D6B4D, 0x00000000} // - greys high contrast
- };
- // char bitMask[] = {128, 64, 32, 16, 8, 4, 2, 1};
- char bitMask[] = {1, 2, 4, 8, 16, 32, 64, 128};
- // 'global' variables to store screen info
- char *fbp = 0;
- struct fb_var_screeninfo vinfo;
- struct fb_fix_screeninfo finfo;
- //------------------
- bool keyPressed(int *character)
- {
- // If this is the first time the function is called, change the stdin
- // stream so that we get each character when the keys are pressed and
- // and so that character aren't echoed to the screen when the keys are
- // pressed.
- if (stdin_fd == -1)
- {
- // Get the file descriptor associated with stdin stream.
- stdin_fd = fileno(stdin);
- // Get the terminal (termios) attritubets for stdin so we can
- // modify them and reset them before exiting the program.
- tcgetattr(stdin_fd, &original);
- // Copy the termios attributes so we can modify them.
- struct termios term;
- memcpy(&term, &original, sizeof(term));
- // Unset ICANON and ECHO for stdin. When ICANON is not set the
- // input is in noncanonical mode. In noncanonical mode input is
- // available as each key is pressed. In canonical mode input is
- // only available after the enter key is pressed. Unset ECHO so that
- // the characters aren't echoed to the screen when keys are pressed.
- // See the termios(3) man page for more information.
- term.c_lflag &= ~(ICANON|ECHO);
- tcsetattr(stdin_fd, TCSANOW, &term);
- // Turn off buffering for stdin. We want to get the characters
- // immediately. We don't want the characters to be buffered.
- setbuf(stdin, NULL);
- }
- // Get the number of characters that are waiting to be read.
- int characters_buffered = 0;
- ioctl(stdin_fd, FIONREAD, &characters_buffered);
- // Set the return value to true if there are any characters to be read.
- bool pressed = (characters_buffered != 0);
- if (characters_buffered == 1)
- {
- // There is only one character to be read. Read it in.
- int c = fgetc(stdin);
- // Check if the caller wants the value of character read.
- if (character != NULL)
- {
- *character = c;
- }
- }
- else if (characters_buffered > 1)
- {
- // There is more than one character to be read. This can be key such
- // as the arrow keys or function keys. This code just reads them in
- // and ignores them. The caller will be informed that a key was
- // pressed, but won't get a value for the key.
- while (characters_buffered)
- {
- fgetc(stdin);
- --characters_buffered;
- }
- }
- return pressed;
- }
- void keyboardReset(void)
- {
- if (stdin_fd != -1)
- {
- // If keyPressed() has been called the terminal input has been
- // changed for the stdin stream. Put the attributes back the way
- // we found them.
- tcsetattr(stdin_fd, TCSANOW, &original);
- }
- }
- //------------------
- void draw()
- {
- int b, p;
- int counter = 0;
- char tempByte;
- unsigned int pix_offset = 0;
- for (b = 0; b < 1024; b++) // 128 x 64 / 8 = 1024
- {
- tempByte = serialGetchar(fd);
- for (p = 0; p < 8; p++) // 8 pixels per byte
- {
- if (tempByte & bitMask[p])
- {
- *((unsigned long*)(fbp + pix_offset)) = paletteArray[paletteSelected][0];
- *((unsigned long*)(fbp + (pix_offset + 512))) = paletteArray[paletteSelected][0];
- }
- else
- {
- *((unsigned long*)(fbp + pix_offset)) = paletteArray[paletteSelected][3];
- *((unsigned long*)(fbp + (pix_offset + 512))) = paletteArray[paletteSelected][3];
- }
- pix_offset = pix_offset + 1024;
- }
- counter++;
- if (counter == 128)
- {
- pix_offset = pix_offset - 508;
- counter = 0;
- }
- else
- {
- pix_offset = pix_offset - 8188;
- }
- }
- }
- // application entry point
- int main(int argc, char* argv[])
- {
- int fbfd = 0;
- struct fb_var_screeninfo orig_vinfo;
- long int screensize = 0;
- if ((fd = serialOpen ("/dev/ttyACM0", 115200)) < 0)
- {
- fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
- return 1 ;
- }
- if (wiringPiSetup () == -1)
- {
- fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
- return 1 ;
- }
- // Open the file for reading and writing
- fbfd = open("/dev/fb0", O_RDWR);
- if (fbfd == -1) {
- printf("Error: cannot open framebuffer device.\n");
- return(1);
- }
- printf("The framebuffer device was opened successfully.\n");
- // Get variable screen information
- if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
- printf("Error reading variable information.\n");
- }
- printf("Original %dx%d, %dbpp\n", vinfo.xres, vinfo.yres,
- vinfo.bits_per_pixel );
- // Store for reset (copy vinfo to vinfo_orig)
- memcpy(&orig_vinfo, &vinfo, sizeof(struct fb_var_screeninfo));
- // Change variable info - force 16 bit and 256 x 128 resolution
- vinfo.bits_per_pixel = 16;
- vinfo.xres = 256;
- vinfo.yres = 128;
- vinfo.xres_virtual = 256;
- vinfo.yres_virtual = 128;
- if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)) {
- printf("Error setting variable information.\n");
- }
- // Get fixed screen information
- if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
- printf("Error reading fixed information.\n");
- }
- // hide cursor
- char *kbfds = "/dev/tty";
- int kbfd = open(kbfds, O_WRONLY);
- if (kbfd >= 0) {
- ioctl(kbfd, KDSETMODE, KD_GRAPHICS);
- }
- else {
- printf("Could not open %s.\n", kbfds);
- }
- // map fb to user mem
- screensize = finfo.smem_len;
- fbp = (char*)mmap(0,
- screensize,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fbfd,
- 0);
- //------------
- int c = 0;
- //------------
- if ((int)fbp == -1) {
- printf("Failed to mmap.\n");
- }
- else
- {
- // draw...
- while (c != 27)
- {
- if (keyPressed(&c))
- {
- if (c == 49) {paletteSelected = 0;} // KEY_1
- else if (c == 50) {paletteSelected = 1;} // KEY_2
- else if (c == 51) {paletteSelected = 2;} // KEY_3
- else if (c == 52) {paletteSelected = 3;} // KEY_4
- else if (c == 53) {paletteSelected = 4;} // KEY_5
- else if (c == 54) {paletteSelected = 5;} // KEY_6
- else if (c == 55) {paletteSelected = 6;} // KEY_7
- else if (c == 56) {paletteSelected = 7;} // KEY_8
- else if (c == 57) {paletteSelected = 8;} // KEY_9
- else if (c == 48) {paletteSelected = 9;} // KEY_0
- else if (c == 45) {paletteSelected = 10;} // KEY_MINUS
- }
- if (serialDataAvail(fd)) {draw();}
- }
- }
- //------------------
- keyboardReset();
- //------------------
- // cleanup
- // unmap fb file from memory
- munmap(fbp, screensize);
- // reset cursor
- if (kbfd >= 0) {
- ioctl(kbfd, KDSETMODE, KD_TEXT);
- }
- // reset the display mode
- if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &orig_vinfo)) {
- printf("Error re-setting variable information.\n");
- }
- // close fb file
- close(fbfd);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement