summaryrefslogtreecommitdiffstats
path: root/lcd.c
diff options
context:
space:
mode:
authorJames <git@panaceas.org>2014-05-05 17:50:20 +0100
committerJames <git@panaceas.org>2014-05-05 17:50:20 +0100
commit470457e22a1b5537013603d5e367c51e47bb61bf (patch)
tree6b72d32bfd9eaec31c8c520d18782ccaebc01759 /lcd.c
downloadkmd_usb-470457e22a1b5537013603d5e367c51e47bb61bf.tar.gz
kmd_usb-470457e22a1b5537013603d5e367c51e47bb61bf.tar.bz2
kmd_usb-470457e22a1b5537013603d5e367c51e47bb61bf.zip
fish
Diffstat (limited to 'lcd.c')
-rw-r--r--lcd.c328
1 files changed, 328 insertions, 0 deletions
diff --git a/lcd.c b/lcd.c
new file mode 100644
index 0000000..cd652b3
--- /dev/null
+++ b/lcd.c
@@ -0,0 +1,328 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include "libdpf/dpf.h"
+
+typedef struct
+{
+ unsigned char R;
+ unsigned char G;
+ unsigned char B;
+ unsigned char A;
+} RGBA;
+
+static DPFContext *dpf;
+static RGBA *fb;
+static RGBA *fbo;
+static uint8_t *fb_16;
+
+
+
+
+void
+lcd_on (void)
+{
+ DPFValue val;
+ if (!dpf)
+ return;
+ val.type = TYPE_INTEGER;
+ val.value.integer = 7;
+ dpf_setproperty (dpf, PROPERTY_BRIGHTNESS, &val);
+}
+
+
+
+void
+lcd_off (void)
+{
+ DPFValue val;
+ if (!dpf)
+ return;
+ val.type = TYPE_INTEGER;
+ val.value.integer = 0;
+ dpf_setproperty (dpf, PROPERTY_BRIGHTNESS, &val);
+}
+
+
+
+
+void
+lcd_close (void)
+{
+ if (!dpf)
+ return;
+ dpf_close (dpf);
+ dpf = NULL;
+ free (fb);
+ free (fb_16);
+}
+
+#define _RGB565_0(p) \
+ (( (((p)->R) & 0xf8) ) | ((((p)->G) & 0xe0) >> 5))
+#define _RGB565_1(p) \
+ (( (((p)->G) & 0x1c) << 3 ) | ((((p)->B) & 0xf8) >> 3))
+
+
+static int
+find_dr (short *rect)
+{
+ RGBA *p = fb, *po = fbo;
+ int e;
+ int x, y;
+ rect[0] = dpf->width;
+ rect[1] = dpf->height;
+ rect[2] = 0;
+ rect[3] = 0;
+
+ for (y = 0; y < dpf->height; y++)
+ {
+ e = 0;
+ for (x = 0; x < dpf->width; x++)
+ {
+ if (memcmp (p, po, 4))
+ {
+ if (x < rect[0])
+ rect[0] = x;
+ if (x >= rect[2])
+ rect[2] = x + 1;
+ e = 1;
+ }
+ p++;
+ po++;
+ }
+ if (e)
+ {
+ if (y < rect[1])
+ rect[1] = y;
+ if (y >= rect[3])
+ rect[3] = y + 1;
+ }
+ }
+ return rect[2];
+
+}
+
+static void
+blit (int x1, int y1, int x2, int y2)
+{
+ int r;
+ int c;
+ short rect[4] = { x1, y1, x2, y2 };
+
+ RGBA *p, *rp, *po, *rpo;
+ uint8_t *p_16;
+
+ if (!dpf)
+ return;
+
+ if (x1 == -1)
+ {
+ if (!find_dr (rect))
+ return;
+ }
+
+ rp = fb + (dpf->width * rect[1]) + rect[0];
+ rpo = fbo + (dpf->width * rect[1]) + rect[0];
+
+ p_16 = fb_16;
+
+ for (r = rect[1]; r < rect[3]; r++)
+ {
+ p = rp;
+ po = rpo;
+ for (c = rect[0]; c < rect[2]; c++)
+ {
+ *p_16++ = _RGB565_0 (p);
+ *p_16++ = _RGB565_1 (p);
+ memcpy (po, p, 4);
+ p++;
+ po++;
+ }
+ rp += dpf->width;
+ }
+
+ //printf ("%d %d %d %d\n", rect[0], rect[1], rect[2], rect[3]);
+
+
+ dpf_screen_blit (dpf, fb_16, rect);
+}
+
+
+void
+lcd_vline (int x, int y1, int y2, int r, int g, int b)
+{
+ RGBA c = {.R = r,.G = g,.B = b };
+ RGBA *p = fb;
+ int y;
+
+ if (!dpf)
+ return;
+
+ if (y1 > y2)
+ {
+ y = y1;
+ y1 = y2;
+ y2 = y;
+ }
+
+ p += x + y1 * dpf->width;
+
+
+ for (y = y1; y <= y2; ++y)
+ {
+ memcpy (p, &c, sizeof (c));
+ p += dpf->width;
+ }
+
+}
+
+void
+lcd_hline (int y, int x1, int x2, int r, int g, int b)
+{
+ RGBA c = {.R = r,.G = g,.B = b };
+ RGBA *p = fb;
+ int x;
+
+ if (!dpf)
+ return;
+
+
+ if (x1 > x2)
+ {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+ }
+
+ p += x1 + y * dpf->width;
+
+ for (x = x1; x <= x2; ++x)
+ {
+ memcpy (p, &c, sizeof (c));
+ p++;
+ }
+
+}
+
+void
+lcd_box (int x1, int y1, int x2, int y2, int r, int g, int b)
+{
+ lcd_vline (x1, y1, y2, r, g, b);
+ blit (x1, y1, x1 + 1, y2 + 1);
+ lcd_vline (x2, y1, y2, r, g, b);
+ blit (x2, y1, x2 + 1, y2 + 1);
+ lcd_hline (y1, x1 + 1, x2 - 1, r, g, b);
+ blit (x1 + 1, y1, x2, y1 + 1);
+ lcd_hline (y2, x1 + 1, x2 - 1, r, g, b);
+ blit (x1 + 1, y2, x2, y2 + 1);
+}
+
+#define LCD_SS_A (1 << 0)
+#define LCD_SS_B (1 << 1)
+#define LCD_SS_C (1 << 2)
+#define LCD_SS_D (1 << 3)
+#define LCD_SS_E (1 << 4)
+#define LCD_SS_F (1 << 5)
+#define LCD_SS_G (1 << 6)
+
+void
+lcd_ss (int v, int x1, int y1, int w, int h)
+{
+ int x2 = x1 + w;
+ int y2 = y1 + (h / 2);
+ int y3 = y1 + h;
+
+ int lut[] =
+ { LCD_SS_A | LCD_SS_B | LCD_SS_C | LCD_SS_D | LCD_SS_E | LCD_SS_F,
+ LCD_SS_B | LCD_SS_C,
+ LCD_SS_A | LCD_SS_B | LCD_SS_D | LCD_SS_E | LCD_SS_G,
+ LCD_SS_A | LCD_SS_B | LCD_SS_C | LCD_SS_D | LCD_SS_G,
+ LCD_SS_B | LCD_SS_C | LCD_SS_F | LCD_SS_G,
+ LCD_SS_A | LCD_SS_C | LCD_SS_D | LCD_SS_F | LCD_SS_G,
+ LCD_SS_A | LCD_SS_C | LCD_SS_D | LCD_SS_E | LCD_SS_F | LCD_SS_G,
+ LCD_SS_A | LCD_SS_B | LCD_SS_C,
+ LCD_SS_A | LCD_SS_B | LCD_SS_C | LCD_SS_D | LCD_SS_E | LCD_SS_F |
+ LCD_SS_G,
+ LCD_SS_A | LCD_SS_B | LCD_SS_C | LCD_SS_D | LCD_SS_F | LCD_SS_G,
+ 0
+ };
+
+ int l;
+ int c;
+
+
+ if (v == 0)
+ v = 10;
+
+ l = lut[v];
+
+ printf ("SS %d %x %d %d %d %d %d\n", v, l, x1, x2, y1, y2, y3);
+
+ c = (l & LCD_SS_A) ? 255 : 0;
+ lcd_hline (y1, x1, x2, c, c, c);
+
+ c = (l & LCD_SS_B) ? 255 : 0;
+ lcd_vline (x2, y1, y2, c, c, c);
+
+ c = (l & LCD_SS_C) ? 255 : 0;
+ lcd_vline (x2, y2, y3, c, c, c);
+
+ c = (l & LCD_SS_D) ? 255 : 0;
+ lcd_hline (y3, x1, x2, c, c, c);
+
+ c = (l & LCD_SS_E) ? 255 : 0;
+ lcd_vline (x1, y2, y3, c, c, c);
+
+ c = (l & LCD_SS_F) ? 255 : 0;
+ lcd_vline (x1, y1, y2, c, c, c);
+
+ c = (l & LCD_SS_G) ? 255 : 0;
+ lcd_hline (y2, x1, x2, c, c, c);
+
+ blit (x1, y1, x1 + 1, y3 + 1);
+ blit (x2, y1, x2 + 1, y3 + 1);
+
+ blit (x1, y1, x2 + 1, y1 + 1);
+ blit (x1, y2, x2 + 1, y2 + 1);
+ blit (x1, y3, x2 + 1, y3 + 1);
+
+}
+
+
+
+int
+lcd_open (void)
+{
+ int err;
+ DPFValue val;
+
+
+ err = dpf_open ("usb0", &dpf);
+
+ if (err < 0)
+ {
+ dpf = NULL;
+ return -1;
+ }
+
+
+ val.type = TYPE_INTEGER;
+ val.value.integer = 1;
+ dpf_setproperty (dpf, PROPERTY_ORIENTATION, &val);
+
+
+ fb_16 = malloc (dpf->height * dpf->width * dpf->bpp);
+ fb = malloc (dpf->height * dpf->width * sizeof (RGBA));
+ fbo = malloc (dpf->height * dpf->width * sizeof (RGBA));
+
+ bzero (fb, dpf->height * dpf->width * sizeof (RGBA));
+ blit (0, 0, 320, 240);
+
+
+
+ return 0;
+}