FreeBASIC  0.91.0
gfx_softcursor.c
Go to the documentation of this file.
1 /* Software cursor helper routines */
2 
3 #include "fb_gfx.h"
4 
5 #define CURSOR_W 13
6 #define CURSOR_H 22
7 
8 #define BIT_ENCODE(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) \
9  ((p0)|(p1<<2)|(p2<<4)|(p3<<6)|(p4<<8)|(p5<<10)|(p6<<12)|(p7<<14)|(p8<<16)|(p9<<18)|(p10<<20)|(p11<<22)|(p12<<24))
10 
12 
13 static const unsigned int cursor_data[] = {
14  BIT_ENCODE(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
15  BIT_ENCODE(2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
16  BIT_ENCODE(2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
17  BIT_ENCODE(2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0),
18  BIT_ENCODE(2, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0),
19  BIT_ENCODE(2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0),
20  BIT_ENCODE(2, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0),
21  BIT_ENCODE(2, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0),
22  BIT_ENCODE(2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0),
23  BIT_ENCODE(2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0),
24  BIT_ENCODE(2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0),
25  BIT_ENCODE(2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0),
26  BIT_ENCODE(2, 1, 1, 1, 2, 1, 1, 2, 3, 3, 3, 3, 3),
27  BIT_ENCODE(2, 1, 1, 2, 2, 1, 1, 2, 3, 0, 0, 0, 0),
28  BIT_ENCODE(2, 1, 2, 3, 3, 2, 1, 1, 2, 0, 0, 0, 0),
29  BIT_ENCODE(2, 2, 3, 0, 0, 2, 1, 1, 2, 3, 0, 0, 0),
30  BIT_ENCODE(2, 3, 0, 0, 0, 0, 2, 1, 1, 2, 0, 0, 0),
31  BIT_ENCODE(0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 3, 0, 0),
32  BIT_ENCODE(0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 0, 0),
33  BIT_ENCODE(0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 3, 0),
34  BIT_ENCODE(0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0),
35  BIT_ENCODE(0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0)
36 };
37 
38 static unsigned char *cursor_area;
39 static unsigned int white, black;
40 
42 
44 
45 
46 /*:::::*/
47 static void copy_cursor_area(int x, int y, int from_area)
48 {
49  unsigned char *s, *d;
50  int w, h, s_pitch, d_pitch;
51 
52  w = (MIN(CURSOR_W, __fb_gfx->w - x) * __fb_gfx->bpp);
53  h = MIN(CURSOR_H, __fb_gfx->h - y);
54 
55  if (from_area) {
56  s = cursor_area;
57  d = __fb_gfx->framebuffer + (y * __fb_gfx->pitch) + (x * __fb_gfx->bpp);
58  s_pitch = w;
59  d_pitch = __fb_gfx->pitch;
60  }
61  else {
62  s = __fb_gfx->framebuffer + (y * __fb_gfx->pitch) + (x * __fb_gfx->bpp);
63  d = cursor_area;
64  s_pitch = __fb_gfx->pitch;
65  d_pitch = w;
66  }
67 
68  for (; h; h--) {
69  fb_hMemCpy(d, s, w);
70  s += s_pitch;
71  d += d_pitch;
72  }
73 }
74 
75 
76 /*:::::*/
77 int fb_hColorDistance(int index, int r, int g, int b)
78 {
79  return (((__fb_gfx->device_palette[index] & 0xFF) - r) * ((__fb_gfx->device_palette[index] & 0xFF) - r)) +
80  ((((__fb_gfx->device_palette[index] >> 8) & 0xFF) - g) * (((__fb_gfx->device_palette[index] >> 8) & 0xFF) - g)) +
81  ((((__fb_gfx->device_palette[index] >> 16) & 0xFF) - b) * (((__fb_gfx->device_palette[index] >> 16) & 0xFF) - b));
82 }
83 
84 
85 /*:::::*/
87 {
88  cursor_area = malloc(CURSOR_W * CURSOR_H * __fb_gfx->bpp);
89 
90 #ifdef HOST_DOS
92 #endif
93 
94  if (__fb_gfx->bpp == 1) {
95  white = 15;
96  black = 0;
97  }
98  else {
99  white = fb_hFixColor(__fb_gfx->bpp, 0xFFFFFF);
100  black = fb_hFixColor(__fb_gfx->bpp, 0x000000);
101  }
102 }
103 
104 
105 /*:::::*/
107 {
108 #ifdef HOST_DOS
110 #endif
111  free(cursor_area);
112 }
113 
114 
115 /*:::::*/
116 void fb_hSoftCursorPut(int x, int y)
117 {
118  unsigned char *d, *dest;
119  int w, h, px, py, pixel, count;
120  unsigned int data;
121  const unsigned int *cursor;
122 
123  copy_cursor_area(x, y, FALSE);
124 
125  w = MIN(CURSOR_W, __fb_gfx->w - x);
126  h = MIN(CURSOR_H, __fb_gfx->h - y);
127  dest = __fb_gfx->framebuffer + (y * __fb_gfx->pitch) + (x * __fb_gfx->bpp);
128  cursor = cursor_data;
129  for (py = 0; py < h; py++) {
130  d = dest;
131  data = *cursor++;
132  for (px = 0; px < w;) {
133  pixel = data & 0x3;
134  for (count = 0; (px < w) && ((data & 0x3) == pixel); px++, data >>= 2)
135  count++;
136  if (pixel == 0x3) {
137  if (__fb_gfx->bpp == 4)
138  fb_hPixelSetAlpha4(d, 0x40000000, count);
139  }
140  else {
141  if (pixel)
142  fb_hPixelSet(d, (pixel & 0x1) ? white : black, count);
143  }
144  d += (count * __fb_gfx->bpp);
145  }
146  __fb_gfx->dirty[y + py] = TRUE;
147  dest += __fb_gfx->pitch;
148  }
149 }
150 
151 
152 /*:::::*/
153 void fb_hSoftCursorUnput(int x, int y)
154 {
155  copy_cursor_area(x, y, TRUE);
157 }
158 
159 
160 /*:::::*/
162 {
163  int i, dist, min_wdist = 1000000, min_bdist = 1000000;
164 
165  if (__fb_gfx->bpp > 1)
166  return;
167  for (i = 0; i < 256; i++) {
168  dist = fb_hColorDistance(i, 255, 255, 255);
169  if (dist < min_wdist) {
170  min_wdist = dist;
171  white = i;
172  }
173  dist = fb_hColorDistance(i, 0, 0, 0);
174  if (dist < min_bdist) {
175  min_bdist = dist;
176  black = i;
177  }
178  }
179 }
180